目录
5.追加字符/字符串:push_back、append、operator+=
6.capacity(容量,不包括\0所占空间),max_size,reserve,resize
7.assign赋值,insert插入,erase删除,replace替换
10. find_first_of、find_last_of、find_first_not_of、find_last_not_of
前言:什么是STL?
STL(standard template libaray)意为标准模板库,是C++标准库的重要组成部分
不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架
string类是basic_string类模板使用char实例化的一个模板类,专门用来处理字符/字符串类型,但注意,不能操作多字符或者变长字符的序列,使用时必须包含
static const size_t npos = -1;
npos是无符号整型,定义为-1,也就是无符号整形的最大值4294967295,使用时加上类域 string::npos
- void test_string1()
- {
- //1.string();
- cout << "1." << endl;
- string s1;
- cout << s1 << endl;
-
- //2.string(const char* s)
- cout << "2." << endl;
- string s2("hello world!!!");
- cout << s2 << endl;
-
- //3.string(const string& str)
- cout << "3." << endl;
- string s3(s2);
- cout << s3 << endl;
-
- //4.string(const string& str, size_t pos, size_t len = npos)
- cout << "4." << endl;
- string s4(s3, 6, 4);
- cout << s4 << endl;
- string s5(s3, 6, 20);
- cout << s5 << endl;
- string s6(s3, 6);
- cout << s6 << endl;
-
- //5.string(const char* s, size_t n);
- cout << "5." << endl;
- string s7("hello world", 4);
- cout << s7 << endl;
-
- //6.string(size_t n, char c)
- cout << "6." << endl;
- string s8(5, 'm');
- cout << s8 << endl;
-
- //7.迭代器版本
- cout << "7." << endl;
- string s9("helloooooo");
- string s10(s9.begin(), s9.end() - 5);
- cout << s10 << endl;
- }

- void test_string2()
- {
- //1.string& operator=(const string& str)
- cout << "1." << endl;
- string s1("hello world!");
- string s2("hello string!");
- s1 = s2;
- cout << s1 << endl;
-
- //2.string& operator=(const char* s)
- cout << "2." << endl;
- string s3("ni hao");
- s3 = "hello";
- cout << s3 << endl;
-
- //3.string& operator=(char c)
- cout << "3." << endl;
- string s4("hhhhhh");
- s4 = 'h';
- cout << s4 << endl;
- }

- void test_string3()
- {
- //char& operator[](size_t pos)
- cout << "1." << endl;
- string s1("helloworld!");
- for (size_t i = 0; i < s1.size(); i++)
- {
- cout << s1[i] << " ";
- }
- cout << endl;
-
- //const char& operator[](size_t pos)
- cout << "2." << endl;
- const string s2("helloworld!");
- for (size_t i = 0; i < s2.size(); i++)
- {
- cout << s2[i] << " ";
- }
- cout << endl;
-
- //char& at(size_t pos)
- cout << "3." << endl;
- const string s3("helloat");
- for (size_t i = 0; i < s3.size(); i++)
- {
- cout << s3.at(i) << " ";
- }
- cout << endl;
-
- //const char& at(size_t pos) const
- cout << "4." << endl;
- const string s4("helloat");
- for (size_t i = 0; i < s4.size(); i++)
- {
- cout << s4.at(i) << " ";
- }
- cout << endl;
- }

- void test_for()
- {
- string s("hello world!!");
- for (auto ch : s)
- {
- cout << ch << " ";
- }
- cout << endl;
- }

范围for遍历的底层实际就是迭代器,可以从汇编角度观察到

- void test_string4()
- {
- //正向迭代器 - iterator
- //[s.begin(),s.end()) - 左闭右开
- cout << "1." << endl;
- string s1("hello iterator");
- string::iterator it = s1.begin();
- while (it != s1.end())
- {
- cout << *it << " ";
- it++;
- }
- cout << endl;
-
- //反向迭代器 - reverse_iterator
- //(s.rend(),s.rbegin()] - 左开右闭
- cout << "2." << endl;
- string s2("hello reverse_iterator");
- string::reverse_iterator rit = s2.rbegin();
- while (rit != s2.rend())
- {
- //正/反向迭代器可以通过it修改内容
- *rit = 'x';
- cout << *rit << " ";
- rit++;
- }
- cout << endl;
- cout << s2 << endl;
-
- //常量迭代器 - const_iterator
- cout << "3." << endl;
- const string s3("hello const_iterator");
- //auto cit = s3.begin();自动推导 begin返回什么auto就是什么
- string::const_iterator cit = s3.begin();
- while (cit != s3.end())
- {
- cout << *cit << " ";
- cit++;
- }
- cout << endl;
-
- //反向常量迭代器 - const_reverse_iterator
- cout << "4." << endl;
- const string s4("hello const_reverse_iterator");
- string::const_reverse_iterator crit = s4.rbegin();
- while (crit != s4.rend())
- {
- cout << *crit << " ";
- crit++;
- }
- cout << endl;
- }

- void test_string5()
- {
- cout << "1." << endl;
- string s1("hello push_back");
- s1.push_back('a');
- cout << s1 << endl;
-
- cout << "2." << endl;
- string s2("hello append");
- s2.append("aaaaa");
- cout << s2 << endl;
-
- cout << "3." << endl;
- string s3("hello operator+=");
- s3 += "hehe";
- s3 += 'a';
- cout << s3 << endl;
-
- cout << "4." << endl;
- string s4("hello");
- s4.append(s3.begin(), s3.end() - 5);
- cout << s4 << endl;
- }

- void test_string7()
- {
- cout << "1." << endl;
- string s1("hello");
- cout << s1.max_size() << endl;
- cout << s1.capacity() << endl;
-
- //查看vs下的扩容机制
- cout << "查看vs下的扩容机制:" << endl;
- size_t sz = s1.capacity();
- for (size_t i = 0; i < 100; i++)
- {
- s1.push_back('a');
- if (sz != s1.capacity())
- {
- sz = s1.capacity();
- cout << "capacity:" << sz << endl;
- }
- }
-
- cout << "2." << endl;
- string s2("aaaaaaaaaaaaaaaaa");
- cout << "reserve之前capacity:" << s2.capacity() << endl;
- s2.reserve(1000);//开空间
- cout << "reserve之后capacity:" << s2.capacity() << endl;
- s2.resize(1000,'x');//开空间+初始化
- cout << "resize之后capacity:" << s2.capacity() << endl;
- }

注意:空间只可扩容不可缩小,reverse或者resize开出去的空间多大就是多大,例如第一次reverse(1000)第二次reverse(500)由于第二次比第一次小,空间就按照第一次来算
- void test_string8()
- {
- cout << "1." << endl;
- string s1;
- s1.assign("hehe");
- cout << s1 << endl;
-
- cout << "2." << endl;
- string s2("hello insert");
- s2.insert(1, " OH! ");//在pos为1的位置后插入字符串
- cout << s2 << endl;
- //iterator insert (const_iterator p, char c);
- s2.insert(s2.begin(), 'K');
- cout << s2 << endl;
-
- s2.erase(0, 1);//在0位置向后删除1个字符
- s2.erase(s2.begin() + 2);
- cout << s2 << endl;
-
- cout << "3." << endl;
- string s3("helloworld");
- string s4("zsl");
- s3.replace(0, 5, s4);//将0~5替换成s4
- cout << s3 << endl;
- }

注意:尽量少使用插入,删除,替换这些接口,因为底层实现是要大量挪动数据的,时间复杂度较高
- void test_string9()
- {
- string s1("string.cpp");
- FILE* p = fopen(s1.c_str(), "r");
- assert(p);
- char ch = 0;
- while (ch != EOF)
- {
- ch = fgetc(p);
- cout << ch;
- }
- cout << endl;
-
- s1 += '\0';
- s1 += "hehehe";
- cout << s1 << endl;//以size为结束标准
- cout << s1.c_str() << endl;//以'\0'为结束标准
- }
许多软件的底层使用C语言实现,因为C++兼容C,使用C实现接口,C、C++都可以使用。
例如:fopen是C语言标准库提供的接口,参数不认识string这样的类,所以传参一般要传字符串的首字符地址,就可以使用c_str()这个接口将string类转换为地址,返回值为const char*
- void test_string10()
- {
- //查找文件后缀
- //从前向后找
- cout << "1." << endl;
- string s1("string.cpp");
- size_t pos1 = s1.find(".");
- cout << s1.substr(pos1) << endl;
- //从后向前找
- cout << "2." << endl;
- string s2("hello.world.cpp");
- size_t pos2 = s2.rfind(".");
- cout << s2.substr(pos2) << endl;
- }

注意:find()中传的参数要全部匹配上才可以,与下一条(10.)有明显区别
- void test_string11()
- {
- cout << "1." << endl;
- string s1("hello,This,is,my,world!");
- size_t pos1 = 0;
- while (1)
- {
- pos1 = s1.find_first_of("l,!");
- if (pos1 == string::npos)
- break;
- s1[pos1] = '*';
- cout << s1 << endl;
- }
-
- cout << "2." << endl;
- string s2("hello,This,is,my,world!");
- size_t pos2 = 0;
- while (1)
- {
- pos2 = s2.find_first_not_of("l,!");
- if (pos2 == string::npos)
- break;
- s2[pos2] = ',';
- cout << s2 << endl;
- }
-
- cout << "3." << endl;
- string s3("hello,This,is,my,world!");
- size_t pos3 = 0;
- while (1)
- {
- pos3 = s3.find_last_of("l,!");
- if (pos3 == string::npos)
- break;
- s3[pos3] = '*';
- cout << s3 << endl;
- }
- }

find_first_of、find_last_of:只要有一个匹配上即可
find_first_not_of、find_last_not_of:只要不是这些字符的任意一个即可
除此之外string支持比较大小、支持加法、operator>>/<<,以上为string类使用的高频接口,只讲解了重点,如果想要更全面细致了解,请到下面官方网址查阅官方资料