前言在上一篇string上博文中博主向大家介绍了string类的成员函数默认构造、拷贝构造、赋值运算符重载使用迭代器和operator [ ]遍历和修改字符串并区分了 const_iterator 与普通迭代器的使用场景另外还介绍了容量的相关接口size、rsize、clear、empty、reserve。本篇博主将对string类常见接口作最后介绍例如对字符串进行增、删、查、改以及一些字符串的运算接口后续文章string下会带大家自己实现string类的接口让大家对string类有更深刻的认识前文参考【CSTLstring上】手把手教你使用官方文档高效学习string并熟练使用string的常用接口-CSDN博客目录前言一Modifiers修改字符串内容的操作1.append/operator 重载为成员函数2.operator 重载为全局函数3.push_back尾插4.insert可实现头插5.erase删除6. replace替换二String operations字符串运算1.find / rfind2.c_str3.substr4.find_first_of5.find_last_of / find_not_first_of / find_not_last_of三补充1.getline与operator的区别2.成员变量npos小结一Modifiers修改字符串内容的操作1.append/operator 重载为成员函数append和operator 功能几乎重合我们在日常使用中为了方便大多数时候都是使用 operator。//append void Test_String4() { string s1(hello world); s1.append(every one); cout s1 endl; string s2 have a nice day; s1.append(s2); cout s1 endl; string s3 xxxx; s2.append(s3, 1, 3); cout s2 endl; }运行结果void Test_String5() { string s1(hello world); s1 x; cout s1 endl; s1 yyy; cout s1 endl; string s2(zzzz); s1 s2; cout s1 endl; }运行结果2.operator 重载为全局函数operator 重载为全局函数是莫大的智慧下面我将提供两段代码请读者先自己体会。string s3(hello world); s3 ; s3 hello bit; cout s3 endl; cout s3 xxxx endl; cout xxxx s3 endl;全局函数允许任意一侧进行隐式类型转换保证左右操作数完全对称。成员函数会强制左操作数必须是 string 类型导致 hello s 这样的常见表达式编译失败。这正是 C 标准库将 std::string 的 operator 实现为非成员函数的设计原因也是很多二元运算符如 、 等被推荐为非成员函数的原则。3.push_back尾插代码演示listint lit; lit.push_back(1); lit.push_back(2); lit.push_back(3); string::iterator ret find(s1.begin(), s1.end(), x); if (ret ! s1.end()) { cout 找到x endl; } listint::iterator ret2 find(lit.begin(), lit.end(), 2);4.insert可实现头插insert重载的参数列表和append极为相似。同样的日常使用中尽量避免使用头插因为insert的时间复杂度会明显提高。5.erase删除代码实现void test_string5() { string s1(hello world); cout s1 endl; s1.insert(0, xxx); cout s1 endl; s1.insert(0, 1, #); cout s1 endl; s1.insert(5, 1, #); cout s1 endl; s1.insert(s1.begin(), $); cout s1 endl; string s2(hello world); cout s2 endl; s2.erase(s2.begin()); // 头删 cout s2 endl; s2.erase(0, 1); // 头删 cout s2 endl; s2.erase(5, 2); cout s2 endl; s2.erase(5); cout s2 endl endl; }6. replace替换replace替换一部分——这个接口设计得贼复杂要小心效率不高少用如果是少量数据用没什么大问题要挪动数据谨慎用。假设有一个string类对象s1“hello world”要求将一个空格替换成“%%%”三个%很容易实现string s3(hello world); cout s3 endl; s3.replace(5, 1, %%%); cout s3 endl;如果这个字符串中有十几个空格使用replace效率就太低了。这时我们以前介绍的范围for九耀派上用场了void Test_String2() { string s5(hello world hello everyone); cout s5 endl; string s6; s6.reserve(s5.size()); for (auto ch : s5) { if (ch ! ) { s6 ch; } else { s6 %%%; } } cout s6 endl; }二String operations字符串运算1.find / rfindfind与 rfind重载的参数列表是一样的使用方法也是一样的不同点在于find是从前往后查找rfind是从后往前查找。上文在介绍replace时引入了一个题目把字符串里的空格替换为“%%%”这里可以先用find找到空格再“%%%”替换掉空格。代码实现如下void Test_String3() { // 所有空格替换为%% string s4(hello world hello); cout s4 endl; size_t pos s4.find( ); while (pos ! string::npos) { s4.replace(pos, 1, %%%); // 找下一个空格 pos s4.find( , pos 3); } cout s4 endl; }2.c_str使用场景c_str用于返回string对象的指针C有些接口的参数必须传const char*此时需要调用c_str。如下图3.substr使用场景取字符串的一部分并返回一个新的string对象。一般和find、rfind搭配使用//取文件名后缀 void Test1() { string file(Test.tar.zip); size_t pos file.rfind(.); if (pos ! string::npos) { string suffix file.substr(pos); cout suffix endl; } }4.find_first_of接口说明在当前字符串中查找任意一个与指定字符集合中字符匹配的字符并返回第一次出现的位置。将一个字符串里的‘a’、‘e’、‘i’、‘o’、‘u’全都替换为‘*’。void Test2() { string str(Please, replace the vowels in this sentence by asterisks.); size_t found str.find_first_not_of(abcdefg); while (found ! string::npos) { str[found] *; found str.find_first_not_of(aeiou, found 1); } cout str endl; }运行结果5.find_last_of / find_not_first_of / find_not_last_of使用方法和 find_first_of 基本一致函数名搜索方向匹配条件返回值find_first_of从左向右字符在指定的字符集合中第一个匹配的位置下标未找到返回nposfind_last_of从右向左字符在指定的字符集合中最后一个匹配的位置下标未找到返回nposfind_first_not_of从左向右字符不在指定的字符集合中第一个不匹配的位置下标未找到返回nposfind_last_not_of从右向左字符不在指定的字符集合中最后一个不匹配的位置下标未找到返回npos三补充1.getline与operator的区别 读字符串时碰到空格或换行就停只能读一个词。getline 专门读整行碰到换行才停默认空格啥的都算内容全收下。2.成员变量npos小结至此string的常用接口已基本梳理完毕。本文重点讲解了 Modifiers修改 和 String operations字符串操作 两大模块Modifiers包括 append、operator、operator、push_back、insert、erase、replace 等掌握了如何增、删、改字符串中的内容。String operations涵盖 find/rfind、c_str、substr、find_first_of 及其 _last_of、_not_of 变体可以灵活地在字符串中查找、截取、定位字符。补充了如何区分了 getline 与 operator 的读取行为并认识了成员变量 npos 的作用。string 作为 STL 中最常用的容器之一其接口设计体现了现代 C 的许多重要思想RAII、迭代器、深拷贝与引用计数某些实现、异常安全等。仅仅学会使用是不够的理解其底层实现才能写出更高效、更健壮的代码。因此下一篇我们将从零开始手写一个简化版的 string 类实现构造、析构、拷贝、赋值、常用修改及访问操作。通过亲自实现你将彻底弄清 string 的内存管理、深拷贝与浅拷贝的区别、迭代器的底层封装等问题为日后阅读 STL 源码打下坚实基础。创作不易如果你觉得有帮助欢迎点赞、收藏、评论。我们下篇见