个人主页:Jason_from_China-CSDN博客
所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客
所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客
前言
string
是标准库中的一个类,它位于<string>
头文件中。- 这个类提供了很多方便的功能来处理字符串,比如字符串的拼接、查找、替换等操作。提高了字符串处理的安全性、便捷性和效率,使得 C++ 在文本处理等领域更具优势。
- 这里作为string作为C++优先出现的一个标准库里面的类,促进了C++的进步,但是在接口上面也有点冗余
- 在学习的时候,尽量打开C++的string英语文档,对比学习,这样效率高一点
- 这里是学习C++第一个类,所以这里我会尽量一个一个讲解,详细的深入剖析,会根据网站里的string的类的流程进行讲解,也会讲解如何看C++的英语文档
string - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/string/string/?kw=string- 这一篇章其实是没有什么难度的,只要你学过数据结构,没有学习过数据结构会有一些难度,我会建议先学习数据结构,再学习C++方向,当然不学习也是没有问题的
数据结构系统性学习_Jason_from_China的博客-CSDN博客https://blog.csdn.net/jason_from_china/category_12634899.html- 这里我的讲解思路会从,string的成员函数,迭代器,判空,字符串操作,元素访问,以及string的模拟实现来进行讲解分析
- C/C++官方文档查询:
cppreference.comhttps://en.cppreference.com/w/- C/C++cplusplus文档查询(我自己经常使用文档查询网站):
cppreference.comhttps://en.cppreference.com/w/这个网站是最新的,我喜欢看旧版的搜索,所以可以点击右上角的【Lefacy version】
文档查询的和使用阅读
网站:
这里我们使用C/C++cplusplus文档查询(我自己经常使用文档查询网站):
cplusplus.com/reference/cstdio/https://cplusplus.com/reference/cstdio/
页面查询流程:
新版页面(这里是不能查询的,所以我们可以去老版的页面去查询):
进入老版的使用页面(我们可以进行查询我们需要学习的类):可以看到这里是可以搜索的
搜索string:此时我们进入搜索的页面了
网站查询介绍
对于C++的文档的学习,其实还是建议去直接看英文,直接翻译的话会导致不准确,不精确
从这里我们可以看出来,如果你直接进行翻译的话,就会导致翻译不准确的存在
布局详解
这里我们直接点击进入第一个
可以看见里面有内容的详细介绍
总结:
- 从上述网站的介绍我们可以发现,其实类的学习大部分的时候 需要自己查阅文档的
- 要观看博客,学习类
重点是:前期在博客上面学会查阅文档
:系统的学习一两个类,并且去实现一两个类,把其中的一些小点学会
string必须掌握的
string因为是C++实现比较靠前的类,所以实现的接口很多都是复杂冗余的,真正需要掌握的其实只有那二十几个,不看文档也得会的,这里也会重点讲解,其他的我也会讲解,只是会稍微的带一带,不会那么精细
Member functions (成员函数)
(constructor):构造函数
语法结构解析:
七大语法结构解析:
default (1) string(); //构造copy (2) string (const string& str); //拷贝构造substring (3) string (const string& str, size_t pos, size_t len = npos); //拷贝str的字符串,从pos开始,长度为lenfrom c-string (4) string (const char* s); //直接拷贝整个字符串from sequence (5) string (const char* s, size_t n); //拷贝字符串,从第n个字符串开始,直到结束fill (6) string (size_t n, char c); //指定字符进行构造range (7) template <class InputIterator>string (InputIterator first, InputIterator last); //使用迭代器来构造字符串 //注意:下面就会讲解迭代器,所以这里先做了解
(destructor):析构函数
析构函数这里会自动调用的
operator=:赋值
string (1) string& operator= (const string& str); //赋值字符串c-string (2) string& operator= (const char* s); //赋值字符character (3) string& operator= (char c); //赋值字符
Iterators(迭代器)
前言
string的迭代器也称之为遍历,遍历的方式主要有三种:
- 迭代器
- 下标实现【】
- 范围for
operator[]:元素访问【】
可以读写(1) char& operator[] (size_t pos); //元素访问可读不可写(2) const char& operator[] (size_t pos) const; //元素访问
迭代器(Iterators)
语法结构的实现:
这里的意思是当遇见最后的数值的时候,就会停止,end(),指向最后的数值
代码
//迭代器std::string b3("Hello word 03");string::iterator it1 = b3.begin();while (it1 != b3.end()){cout << *it1;++it1;}printf("\n\n\n");
list(容器)+迭代器
迭代器的主要作用就是与容器结合使用,以提供一种统一的方式来访问容器中的元素。不同的容器可能有不同类型的迭代器,但它们都遵循一些共同的规则和行为。
//list+迭代器的使用list<int> it2;it2.push_back(1);it2.push_back(2);it2.push_back(3);it2.push_back(4);list<int>::iterator it3 = it2.begin();while (it3 != it2.end()){cout << *it3;++it3;}printf("\n\n\n");
范围for(智能遍历)
auto(语法糖)
学习范围for需要学习自动匹配auto,所以我们需要学习一下auto,也就是我们常说的语法糖,因为很甜,用起来很方便,所以叫做语法糖
语法结构讲解:
实现
代码实现:
从代码这里我们可以看出来,auto本质就是自动匹配类型,接下来我们会把auto和范围for进行结合使用
//auto语法糖//auto简单的自动匹配auto bb1 = 1;auto bb2 = 1.1;auto bb3 = 0.1;auto bb4 = 1 / 10;cout << bb1 <<endl<< bb2 << endl<< bb3 << endl << bb4 << endl<< endl << endl;//容器的自动匹配list<int> it4;it4.push_back(1);it4.push_back(2);it4.push_back(3);it4.push_back(4);//list<int>::iterator it4 = it2.begin();auto it5 = it4.begin();while (it5 != it4.end()){cout << *it5;++it5;}printf("\n\n\n");
范围for(智能遍历)语法讲解:
for(auto e(变量名):str(指向的字符串进行遍历)) {//对变量名进行操作 }
实现讲解
代码
//范围forfor (auto ch1 : it4){cout << ch1;}printf("\n\n\n");for (auto ch2 : it4){ch2 = 1;cout << ch2;}printf("\n\n\n");for (auto ch3 : it4){ch3++;cout << ch3;}printf("\n\n\n");
范围for使用的限制(C++11之后才出现的范围for):
修改编译器的标准
auto是C++11开始支持的,C++20支持做参数的,所以我们需要学会修改编译器的标准
begin+end正向迭代
这里本质上就是迭代器的开始和结束,所以不做过多赘述,上面已经开始讲解了
rbegin+rend反向迭代
反向迭代和正向迭代刚好是相反的
其他的都是一样的
//反向迭代器string c1("Hello word");string::reverse_iterator cc1 = c1.rbegin();while (cc1 != c1.rend()){cout << *cc1 << " ";++cc1;}
const修饰和不修饰
const修饰就会
//const修饰和不修饰的问题const string c2("Hello word");//string::const_iterator cc2 = c1.begin();auto cc2 = c1.begin();while (cc2 != c1.end()){cout << *cc2 << " ";++cc2;}printf("\n\n\n");//string::const_reverse_iterator ccc2 = c1.rbegin();auto ccc2 = c1.rbegin();while (ccc2 != c1.rend()){cout << *ccc2 << " ";++ccc2;}printf("\n\n\n");for (auto ch : c2){cout << ch << " ";++ch;}
C++11
Capacity(容量)
前言
这里直接翻译过来的意思是容器的意思,也可以这样理解,但是是不完全正确的,因为这里更多的是计算容器里面字符的长度,以及容器的大小,还有是否是空,所以还是那句话,还是需要读英文文献
size+length(字符串长度)
这里有些是比较简单的,那么我就会图解直接带过
这两个都是计算长度的,但是还是比较推荐size,因为size很多类和库里面都有,因为C++语言发展的原因,所以size兼容性会更好,使用的更广,所以这里推荐使用size
max_size (容器的最大数量)
作用是返回容器所能容纳的元素的最大数量。
resize(扩容缩容,指定字符扩容)
(1) void resize (size_t n); //扩容,缩容(2) void resize (size_t n, char c); //指定字符进行扩容string d1("Hello word");d1.resize(20);d1.resize(2);d1.resize(30,'1');
capacity
string d1("Hello word");d1.resize(20);d1.resize(2);d1.resize(30,'1');cout << d1.capacity();printf("\n\n\n");
reserve(扩容(不改变字符数量))
string d1("Hello word");d1.resize(20);d1.resize(2);d1.resize(30,'1');cout << d1.capacity();d1.reserve(200);printf("\n\n\n");
clear(清除数据)
string d1("Hello word");d1.resize(20);d1.resize(2);d1.resize(30,'1');cout << d1.capacity();d1.reserve(200);d1.clear();printf("\n\n\n");
empty(判空)
C++11
Element access(获取需要的字符)
operator[] (下标访问)
(3) char& operator[] (size_t pos);(3) const char& operator[] (size_t pos) const;报错是断言处理
at
(1) char& at (size_t pos);(2) const char& at (size_t pos) const;//同理,只是加上const
string d1("Hello word");d1.resize(20);d1.resize(2);d1.resize(30,'1');cout << d1.capacity();d1.reserve(200);d1.clear();printf("\n\n\n");越界访问//d1[2000];try{d1.at(1000);}catch (const std::exception& e){cout << e.what() << endl;}
back +front
Modifiers(插入,赋值,交换)
前言
operator+=
string (1) string& operator+= (const string& str);c-string (2) string& operator+= (const char* s);character (3) string& operator+= (char c);string e2("Hello word");cout << e2.back();cout << e2.front();printf("\n\n\n");string f1("Hello word");f1 += 'K';cout << f1 << endl;f1 += " ehfaso ";cout << f1 << endl;f1 += e2;cout << f1 << endl;
append (追加字符串)
这个虽然多,但是不是必须要掌握的
string (1) string& append (const string& str); //substring (2) string& append (const string& str, size_t subpos, size_t sublen); //追加哪一个字符串,从第几个开始,追加长度c-string (3) string& append (const char* s); //追加字符串buffer (4) string& append (const char* s, size_t n); //追加哪一个字符串,从第几个开始,会直接到结束fill (5) string& append (size_t n, char c); //追加指定个数的字符range (6) template <class InputIterator>string& append (InputIterator first, InputIterator last); //迭代器的实现
push_back (尾插)+pop_back (尾删)
assign (拷贝,可以指定,覆盖)
//assign的实现string h1("hello word ");string h2("BU HELLOW WORD ");//拷贝字符串h1.assign(h2);cout << h1 << endl;//拷贝一定的长度h1.assign(h2, 3, 6);cout << h1 << endl;//拷贝字符串h1.assign(h2);cout << h1 << endl;//从第四个开始,一直到结束h1.assign(h2, 4);cout << h1 << endl;//拷贝字符,n个h1.assign(10, '4');cout << h1 << endl;//迭代器的实现h1.assign(h2.begin() + 6, h2.end() - 2);cout << h1 << endl;printf("\n\n\n");
string (1) string& assign (const string& str); //拷贝字符串substring (2) string& assign (const string& str, size_t subpos, size_t sublen); //拷贝一定的长度c-string (3) string& assign (const char* s); //拷贝字符串buffer (4) string& assign (const char* s, size_t n); //拷贝哪一个字符串,从第几个开始,一直到结束fill (5) string& assign (size_t n, char c); //拷贝字符,n个range (6) template <class InputIterator>string& assign (InputIterator first, InputIterator last); //迭代器
insert (指定位置插入)
string (1) string& insert (size_t pos, const string& str); //指定位置插入substring (2) string& insert (size_t pos, const string& str, size_t subpos, size_t sublen); //从第几个开始插入,插入字符串str,长度是哪一个开始,这个字符串一共插入多长c-string (3) string& insert (size_t pos, const char* s); //指定位置插入字符串buffer (4) string& insert (size_t pos, const char* s, size_t n); //指定位置插入字符串,插入字符串的个数fill (5) string& insert (size_t pos, size_t n, char c);void insert (iterator p, size_t n, char c); //指定位置插入指定字符,可以插入指定个数
single character (6) iterator insert (iterator p, char c); //迭代器的方式选择插入的位置,插入一个字符
range (7) template <class InputIterator>void insert (iterator p, InputIterator first, InputIterator last); //迭代器的方式选择插入的位置,选择插入的长度
//insert的使用string j1("hello word ");string j2("BU HELLOW WORD ");//指定位置插入j1.insert(2, j2);cout << j1 << endl;//从第0个开始插入,插入字符串j2,j2的长度是0个开始,15个j1.insert(0, j2, 0, 15);cout << j1 << endl;//从第几个位置开始插入数值j1.insert(0, j2);cout << j1 << endl;//指定位置插入字符串,插入字符串的个数j1.insert(0, j2, 1);cout << j1 << endl;//指定位置插入指定字符,可以插入指定个数j1.insert(0, 5, '1');cout << j1 << endl;//迭代器的方式选择插入的位置j1.insert(j1.begin(), '1');cout << j1 << endl;//迭代器的方式选择插入的位置,选择插入的长度j1.insert(j1.begin(), j1.begin(), j1.end());cout << j1 << endl;
erase(删除字符串)
sequence (1) string& erase (size_t pos = 0, size_t len = npos); //从第几个位置开始删除几个字符 //注意删除字符是不改变空间容量大小的character (2) iterator erase (iterator p); //迭代器删除一个下标range (3) iterator erase (iterator first, iterator last); //迭代器删除一个整个字符//erasestring k1("hello word 1111111111111111111111111111111111111111");string k2("BU HELLOW WORD 1111111111111111111111111111111111111111");//从第几个位置开始删除几个字符cout << k1.capacity() << endl;k1.erase(5, 5);cout << k1 << endl;cout << k1.capacity() << endl;printf("\n\n\n");//迭代器删除一个下标cout << k2 << endl;k2.erase(k2.begin());cout << k2 << endl;printf("\n\n\n");//迭代器删除一个整个字符cout << k2 << endl;k2.erase(k2.begin(), k2.end());cout << k2 << endl;printf("\n\n\n");
replace(更换字符串)
string (1) string& replace (size_t pos, size_t len, const string& str); string& replace (iterator i1, iterator i2, const string& str); //从第4个开始,一直到结束,这个区间替换为l2,不建议过多使用,因为设计扩容和后移的问题//这里我们还可以从寻找到的开始,替换掉y1的长度为5的字符,替换为j
substring (2) string& replace (size_t pos, size_t len, const string& str,size_t subpos, size_t sublen); //选择需要替换的字符串长度,选择长度c-string (3) string& replace (size_t pos, size_t len, const char* s); string& replace (iterator i1, iterator i2, const char* s); //选择指定长度,替换为你需要的字符串buffer (4) string& replace (size_t pos, size_t len, const char* s, size_t n); string& replace (iterator i1, iterator i2, const char* s, size_t n); //这里指定更改字符串fill (5) string& replace (size_t pos, size_t len, size_t n, char c); string& replace (iterator i1, iterator i2, size_t n, char c); //更换指定位置的字符range (6) template <class InputIterator>string& replace (iterator i1, iterator i2,InputIterator first, InputIterator last); //迭代器的实现更换//replace//从第4个开始,一直到结束,这个区间替换为l2,不建议过多使用,因为设计扩容和后移的问题string l1("1111111111111111111111111111111111111111 ");string l2("2222222222222222222222222222222222222222 ");l1.replace(4, l1.size(), l2);cout << l1 << endl;printf("\n\n\n");//区间直接进行替换string l3("1111111111111111111111111111111111111111 ");string l4("hhhhhhhhh ");l3.replace(l3.begin(), l3.end(), l4);cout << l3 << endl;printf("\n\n\n");//选择需要替换的字符串长度,选择长度//l5的全部字符串,替换为l6字符串的前五个字符串string l5("1111111111111111111111111111111111111111 ");string l6("hello word");l5.replace(0, l5.size(), l6, 0, 5);cout << l5 << endl;printf("\n\n\n");string l7("1111111111111111111111111111111111111111 ");string l8("hello word");l7.replace(0, l7.size(), "dsfdfs");cout << l7 << endl;printf("\n\n\n");string l9("1111111111111111111111111111111111111111 ");l9.replace(0, l9.size(), "hello", 2);cout << l9 << endl;printf("\n\n\n");//把从0开始的数值,更换为数值pstring l11("1111111111111111111111111111111111111111 ");string l12("hello word");l11.replace(0, l11.size(), l11.size(), 'p');cout << l11 << endl;printf("\n\n\n");//利用迭代器实现更换string l13("1111111111111111111111111111111111111111 ");string l14("hello word");l13.replace(l13.begin(), l13.end(), l14.begin(), l14.end());cout << l13 << endl;
swap(交换)
string i1("hello word ");string i2("BU HELLOW WORD ");i1.swap(i2);cout << i1 << endl;
String operations(兼容,替换,查找)
前言
这一篇章已经到最后一篇章了,所以难度会降低很多
c_str (兼容C语言)
这里存在的意义主要就是为了兼容C语言,因为C++不仅是面向对象的,而且还有很多C语言的接口,所以为了实现兼容C语言,所以出现了这样的,进行匹配
data(同理和C_str)
copy(拷贝)
把指定字符串放到数组里面,选择开始拷贝的位置
find(查找)+rfind(逆置查找)
查找一般是和替换一起使用的
也就是replace
find
string (1) size_t find (const string& str, size_t pos = 0) const;c-string (2) size_t find (const char* s, size_t pos = 0) const;buffer (3) size_t find (const char* s, size_t pos, size_t n) const;character (4) size_t find (char c, size_t pos = 0) const;//查找std::string w1("hello word ");std::string w2("hello word ");size_t i = w1.find(' ');while (i != string::npos){w1.replace(i, 1, "$$");i = w1.find(' ');}cout << w1;printf("\n\n\n");w1 = w2;//这里需要新创建一个std::string w3;std::string w4(" hello word ");for (auto ch : w4){if (ch != ' ')w3 += ch;elsew3 += '*';}cout << w3;
rfind
string (1) size_t rfind (const string& str, size_t pos = npos) const;c-string (2) size_t rfind (const char* s, size_t pos = npos) const;buffer (3) size_t rfind (const char* s, size_t pos, size_t n) const;character (4) size_t rfind (char c, size_t pos = npos) const;
find_first_of(替换)+find_last_of(替换)
find_first_not_of(不替换)find_last_not_of(不替换)