个人主页: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(指向的字符串进行遍历)) { //对变量名进行操作 }
实现讲解
代码
//范围for for (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); //迭代器删除一个整个字符//erase string 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开始的数值,更换为数值p string 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; else w3 += '*'; } 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(不替换)