微信小程序和网站开发有什么区别,软文小故事200字,我想自己做网站可以赚钱,ppt设计大赛string类 为什么学习string类#xff1f; C语言中的字符串 C语言中#xff0c;字符串是以\0结尾的一些字符的集合#xff0c;为了操作方便#xff0c;C标准库中提供了一些str系列 的库函数#xff0c;但是这些库函数与字符串是分离开的#xff0c;不太符合OOP的思想string类的常用接口说明函数名称功能说明string() 重点构造空的string类对象即空字符串string(const char* s) 重点用C-string来构造string类对象string(size_t n, char c)string类对象中包含n个字符cstring(const strings) 重点拷贝构造函数string类对象的访问及遍历操作函数名称功能说明operator[]返回pos位置的字符const string类对象调用beginendbegin获取一个字符的迭代器 end获取最后一个字符下一个位 置的迭代器rbeginrendrbegin 获取指向最后一个字符的反向迭代器 rend 获取指向第一个字符前一个位置的反向迭代器范围forC11支持更简洁的范围for的新遍历方式#includeiostream #includeassert.h #includestring//使用string必须包含的头文件跟C的string.h不同 using namespace std; //string里的operate [] //语法char operator[] (size_t pos)//访问pos位置的字符并返回其引用 //operator[]的底层实现 //class string //{ //public: // char operator[](size_t i) // { // assert(i _size); // return _str[i]; // } //private: // char* _str; // size_t _size; // size_t _capacity; //}; int main() { string s1;//string(); 构造函数是一个空串 string s2(hello world); string s3(s2);//string (const string str); 将s2拷贝构造给s3 cout s1 endl; cout s2 endl; cout s3 endl; //string (const string str, size_t pos, size_t len npos); string s4(s2, 6, 15);//从s2中第6个字符开始复制15个字符到s4如果复制数量超过s2就有多少拷多少 cout s4 endl; string s5(s2, 6);//不传第三个参数就直到拷贝结束 cout s5 endl; //string (const char* s, size_t n); string s6(hello world, 5);//拷贝前5个字符给s6初始化 cout s6 endl; //string(size_t n, char c); string s7(10, X); //用10个X初始化s7 cout s7 endl; //string能够直接访问修改数组的内容并能检测数组是否越界 //数组名[]字符 s6[0] x;//将数组下标0的字符修改为‘x’ //s6[10];//如果数组越界能够检查出来 cout s6 endl; return 0; }auto和范围forauto关键字这两个都是C11的小语法1.在早期C/C中auto的含义是使用auto修饰的变量是具有自动存储器的局部变量后来这个 不重要了。C11中标准委员会变废为宝赋予了auto全新的含义即auto不再是一个存储类型 指示符而是作为一个新的类型指示符来指示编译器auto声明的变量必须由编译器在编译时期 推导而得。2.用auto声明指针类型时用auto和auto*没有任何区别但用auto声明引用类型时则必须加。3.当在同一行声明多个变量时这些变量必须是相同的类型否则编译器将会报错因为编译器实际 只对第一个类型进行推导然后用推导出来的类型定义其他变量。4.auto不能作为函数的参数可以做返回值但是建议谨慎使用。5.auto不能直接用来声明数组。范围for1.对于一个有范围的集合而言由程序员来说明循环的范围是多余的有时候还会容易犯错误。因此 C11中引入了基于范围的for循环。for循环后的括号由冒号“ ”分为两部分第一部分是范围 内用于迭代的变量第二部分则表示被迭代的范围自动迭代自动取数据自动判断结束。2.范围for可以作用到数组和容器对象上进行遍历。3.范围for的底层很简单容器遍历实际就是替换为迭代器这个从汇编层也可以看到。下面是两个语法示例#includeiostream #includelist using namespace std; //class string //{ // private: // char* _str; // size_t _size; // size_t _capacity; //}; void test_string() { string s1; string s2(hello world!); cout s1 s2 endl; //遍历string的三种方法 //1.下标[] for (size_t i 0; i s2.size(); i)//string中的size接口 { cout s2[i] ;//h e l l o w o r l d ! } cout endl; //2.迭代器用来遍历和访问容器 string::iterator it s2.begin();//串 while (it ! s2.end()) { //it 2;迭代器是可以修改的 cout *it ;//h e l l o w o r l d ! it; } cout endl; listint lt { 1,2,3,4,5,6,7 };//链表 listint::iterator lit lt.begin(); while (lit ! lt.end()) { cout *lit ;//解引用返回 lit; } cout endl; //其他容器使用迭代器访问都是类似的通用的 //3.范围for遍历 //字符赋值自动迭代自动判断结束 //底层就是迭代器也是跟迭代器一样支持所有容器 for (auto ch : s2)//auto自动类型这里也可以自己写char只要类型匹配即可 //for (auto ch : s2) //上面的只是拷贝修改不了s2只有加个引用才能修改s2 { //ch - 2; cout ch ; } cout endl; //以上三种遍历方式没有区别 } int main() { test_string(); return 0; }上面用到的迭代器还有四种//4种迭代器 //iterator //reverse_iterator //const_iterator //const_reverse_iterator void test_string2() { string s2(hello world); string::iterator it s2.begin();//正向迭代器 while (it ! s2.end()) { cout *it ; //h e l l o w o r l d it; } cout endl; string::reverse_iterator rit s2.rbegin();//反向迭代器 while (rit ! s2.rend()) { cout *rit ;//d l r o w o l l e h rit; } cout endl; const string s3(hello world!);//const迭代器遍历const对象 string::const_iterator cit s3.begin(); while (cit ! s3.end()) { cout *cit ; cit; } cout endl; //string::const_reverse_iterator rcit s3.rbegin();//const反向迭代器 auto rcit s3.rbegin();//auto指针的好处节省代码量 while (rcit ! s3.rend()) { cout *rcit ; rcit; } cout endl; } int main() { test_string2(); return 0; }迭代器是一种封装的体现。指向无论什么容器什么数据结构接口begin指向容器的第一个位置end指向最后一个数据的下一个位置。它屏蔽了实现细节提供了统一的方式去访问数据结构我们使用时不用关心该数据结构单向还是双向循环还是不循环它都是类似的方式进行访问便利互通。迭代器底层是一个物理数组string类对象的容量操作函数名称功能说明size重点返回字符串有效字符长度length返回字符串有效字符长度capacity返回空间总大小empty 重点检测字符串释放为空串是返回true否则返回falseclear 重点清空有效字符reserve 重点为字符串预留空间resize 重点将有效字符的个数该成n个多出的空间用字符c填充注意1. size()与length()方法底层实现原理完全相同引入size()的原因是为了与其他容器的接 口保持一致一般情况下基本都是用size()。2.clear()只是将string中有效字符清空不改变底层空间大小。3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个不 同的是当字符个数增多时resize(n)用0来填充多出的元素空间resize(size_t n, char c)用字符c来填充多出的元素空间。注意resize在改变元素个数时如果是将元素个数 增多可能会改变底层容量的大小如果是将元素个数减少底层空间总大小不变。4.reserve(size_t res_arg0)为string预留空间不改变有效元素个数当reserve的参 数小于string的底层空间总大小时reserver不会改变容量大小。以上各函数使用示例void TestPushBack() { //reverse 反转 逆置 //reverve 保留 预留 string s; size_t sz s.capacity(); s.reserve(100);//提前开空间避免扩容 cout capacity changed: sz \n; cout making s grow:\n; for (int i 0; i 100; i) { s.push_back(c); if (sz ! s.capacity()) { sz s.capacity(); cout capacity changed: sz \n; } } } void test_string3() { string s2(hello world); //下面两个作用都是返回字符串有效字符长度 cout s2.length() endl; cout s2.size() endl; cout s2.max_size() endl;//最大长度 cout s2.capacity() endl;//返回空间总大小 TestPushBack(); string s3(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); } void test_string4() { //reserve在vs平台不会缩容在g会缩容具体看平台实现 string s2(hello worldxxxxxxxxxxxxxxx); cout s2.size() endl;//26 cout s2.capacity() endl endl;//31\0占了一位对齐32 s2.reserve(20);//202631 在g平台下这里会缩容capacity会输出26 cout s2.size() endl;//26 cout s2.capacity() endl endl;//31没缩容 s2.reserve(28);//262831 cout s2.size() endl;//26 cout s2.capacity() endl endl;//31 s2.reserve(48);//263148 cout s2.size() endl;//26 cout s2.capacity() endl endl;//63 扩容 //clear 清数据但不清容量 s2.clear(); cout s2.size() endl;//0 cout s2.capacity() endl endl;//63 } int main() { test_string3(); test_string4(); return 0; }string类对象的修改操作函数名称功能说明pushback在字符串后尾插字符cappend在字符串后追加一个字符串operator (重 点)在字符串后追加字符/字符串c_str(重点)返回C格式字符串findnpos(重点)从字符串pos位置开始往后找字符c返回该字符在字符串中的 位置rfind从字符串pos位置开始往前找字符c返回该字符在字符串中的 位置substr在str中从pos位置开始截取n个字符然后将其返回insert在pos位置插入n个字符/字符串void test_string5() { //尾插push_backappend 接口 string s(hello world); s.push_back( ); s.push_back(x); s.append(yyyyyy); cout s endl;//hello world xyyyyyy s ;//也是尾插一般用这个多一些 s 33333333333; cout s endl;//hello world xyyyyyy 33333333333 //指定位置插入insert接口 s.insert(0, hello gym); cout s endl;//hello gymhello world xyyyyyy 33333333333 s.insert(0, p);//插入一个字符 cout s endl;//phello gymhello world xyyyyyy 33333333333 // string insert (size_t pos, size_t n, char c); char ch t; s.insert(0, 1, ch);//pos位置插入n个字符 s.insert(s.begin(), ch);//迭代器版本头插 cout s endl;//ttphello gymhello world xyyyyyy 33333333333 } void test_string6() { string s(hello world); //指定位置删除erase接口 // string erase (size_t pos 0, size_t len npos);pos位置开始删len个字符 s.erase(6, 1); cout s endl;//hello orld s.erase(0, 1); cout s endl;//ello orld //迭代器用法 s.erase(s.begin());//头删 cout s endl;//llo orld s.erase(--s.end());//尾删 cout s endl;//llo orl s.erase(2);//从下标2开始后面全部删除 cout s endl;//ll //指定位置替换replace //string replace (size_t pos, size_t len, const string str); string ss(hello world); //replace的本质伴随着插入删除 ss.replace(5,1,##);//第5个位置的一个字符替换成两个# cout ss endl;//hello##world //sss.replace(5, 4, ##);//第5个位置的四个字符替换成一个# //cout sss endl;//hello##ld //查找find从左开始找/rfind(从右开始找) //例题找出字符串的空格并替换成## string sss(hello world hello gym); size_t pos sss.find( ); while (pos ! string::npos) { sss.replace(pos, 1, ##); pos sss.find( ,pos2); } cout sss endl;//hello##world##hello##gym } void test_string7() { string str(Please,replace the vowe in this sentence by asterisks.); cout str endl; size_t found str.find_first_of(abcd);//找到abcd任意一个将其替换成‘*’ while (found ! string::npos) { str[found] *; found str.find_first_of(abcd, found 1); } cout str endl; }注意 1. 在string尾部追加字符时s.push_back(c) / s.append(1, c) / s c三种的实现方式差 不多一般情况下string类的操作用的比较多操作不仅可以连接单个字符还可 以连接字符串。2. 对string操作时如果能够大概预估到放多少字符可以先通过reserve把空间预留 好避免频繁扩容。string类非成员函数函数功能说明operator构造一个新的字符串对象尽量少用因为传值返回导致深拷贝效率低operator 重点输入运算符重载operator 重点输出运算符重载getline 重点获取一行字符串relational operators 重点大小比较上面的几个接口大家了解一下string类中还有 一些其他的操作这里不一一列举大家在需要用到时不明白查string文档即可。string类的模拟实现1.string基础部分基本组成初始化销毁打印遍历模拟实现迭代器,下标访问string.h:#pragma once #includeiostream #includeassert.h using namespace std; namespace zwg { class string { public: //模拟实现迭代器模拟的是指针的行为 typedef char* iterator; typedef const char* const_iterator ;//const迭代器 iterator begin()//开头 { return _str; } iterator end()//结尾 { return _str_size; } const_iterator begin()const { return _str; } const_iterator end()const { return _str _size; } string(const char* str)//常量字符串后面都有一个\0,如果写成‘\0’就会有两个\0 { _size strlen(str); _capacity _size; _str new char[_capacity 1];//_capacity不包含\0,因此开空间的时候多开一个 strcpy(_str, str); } ~string() { delete[]_str; _str nullptr; _size _capacity 0; } const char* c_str()const//还没重载“”,只能先用着c_str函数实现输出 { return _str; } char operator[](size_t pos) { assert(pos _size); return _str[pos]; } const char operator[](size_t pos)const { assert(pos _size); return _str[pos]; } size_t size()const { return _size; } size_t capacity()const { return _capacity; } private: char* _strnullptr; size_t _size0; size_t _capacity0; static const size_t npos; }; }string.cpp:#includestring.h namespace zwg { void test_string1() { string s1; string s2(hello world); cout s1.c_str() endl; cout s2.c_str() endl; //下标遍历 for (size_t i 0; i s2.size(); i) { s2[i] 2; } cout s2.c_str() endl; //以下两种遍历需要自行实现一个迭代器 //迭代器遍历 string::iterator it s2.begin(); while (it ! s2.end()) { *it 2; cout *it ; it; } cout endl; //范围for遍历 for (auto a : s2) { cout a ; } cout endl; } }在自定义命名空间里模拟实现string是防止与库里面的string发生冲突·。2.pushback尾插字符append尾插字符串isert(指定位置前插入字符/字符串),erase从指定位置开始删除len个字符的实现string.cpp:namespace zwg { const size_t string::npos -1;//声明跟定义分离 void string::reserve(size_t n) { //手动扩容 if (n _capacity) { //开辟新空间拷贝数据释放旧空间指向新空间 char* tmp new char[n 1];//多开一个给\0 strcpy(tmp, _str); delete[] _str; _str tmp; _capacity n; } } //尾插字符 void string::push_back(char ch) { if (_size _capacity) { reserve(_capacity 0 ? 4 : 2 * _capacity); } _str[_size] ch; _size; _str[_size] \0;//不要漏了否则会乱码 } string string::operator(char ch) { push_back(ch); return *this; } //尾插字符串 void string::append(const char* str) { size_t len strlen(str); if (_size len _capacity) { reserve(_size len 2 * _capacity ? _size len : 2 * _capacity); } strcpy(_str _size, str);//strcpy会自动拷贝\0 _size len; } string string::operator(const char* str) { append(str); return *this; } //从pos位置插入字符 void string::insert(size_t pos, char ch) { assert(pos _size); if (_size _capacity)//需要扩容的情况 { reserve(_capacity 0 ? 4 : 2 * _capacity); } //挪动数据 size_t end _size1; while (end pos) { _str[end ] _str[end-1]; --end; } _str[pos] ch; _size; } //从pos位置插入字符串 void string::insert(size_t pos, const char* str) { assert(pos _size); size_t len strlen(str); if (len 0) return; if (_size len _capacity) { reserve(_size len 2 * _capacity ? _size len : 2 * _capacity); } //向后挪动数据 size_t end _size len; while (end poslen-1)//注意位置关系 { _str[end] _str[end - len]; --end; } //插入数据 for (size_t i 0; i len; i) { _str[pos i] str[i]; } _size len; } //删除从pos位置开始的len个字符 void string::erase(size_t pos, size_t len) { assert(pos _size); if (len _size-pos) { _str[pos] \0; _size pos; } else { for (size_t i poslen; i _size; i) { _str[i - len] _str[i]; } _size - len; } } }3.find(查找字符/查找字符串)string深拷贝的实现string.cpp:namespace zwg { //查找字符 size_t string::find(char ch, size_t pos) { assert(pos _size); for (size_t i pos; i _size; i) { if (_str[i] ch) { return i; } } return npos; } //查找字符串 size_t string::find(const char* str, size_t pos) { assert(pos _size); const char* ptr strstr(_str pos, str);//采用strstr算法 if (ptr nullptr)//没找到的情况 { return npos; } else { return ptr - _str;//找到的位置减去起始位置的下标 } } //深拷贝 string string::operator(const string s) { if (this ! s)//防止自己赋值给自己出现问题 { delete[] _str;//释放旧空间 _str new char[s._capacity 1];//开辟新空间 strcpy(_str, s._str);//将数据拷贝到新空间 _size s._size; _capacity s._capacity; } return *this; } }4.比较大小,,,,!的重载:string.cpp:namespace zwg { //比较大小(与库里面一样实现成全局函数) //实现两个就可以开始代码复用 bool operator(const string s1, const string s2) { return strcmp(s1.c_str(), s2.c_str()) 0; } bool operator(const string s1, const string s2) { return !(s1 s2); } bool operator(const string s1, const string s2) { return !(s1 s2); } bool operator(const string s1, const string s2) { return !(s1 s2); } bool operator(const string s1, const string s2) { return strcmp(s1.c_str(), s2.c_str())0; } bool operator!(const string s1, const string s2) { return !(s1 s2); } }5.重载流插入流提取的实现string.cpp:namespace zwg { //重载流插入流提取运算符 //实现成全局函数 ostream operator(ostream out, const string s) { for (auto ch : s) { out ch; } return out; } istream operator(istream in, string s) { s.clear(); const int N 256; char buff[N];//设一个缓冲,减少空间浪费 int i 0; //cin/scanf提取不到空格和换行符默认它们是分隔符。 //所以用get函数来规避这一问题。 char ch; ch in.get(); while (ch ! ch ! \n) { buff[i]ch; if (i N - 1) { buff[i] \0; s buff; i 0; } chin.get(); } if (i 0)//buff没存满的情况 { buff[i] \0; s buff; } return in; } }参考代码string.h:#pragma once #includeiostream #includeassert.h using namespace std; namespace zwg { class string { public: //模拟实现迭代器模拟的是指针的行为 typedef char* iterator; typedef const char* const_iterator ;//const迭代器 iterator begin()//开头 { return _str; } iterator end()//结尾 { return _str_size; } const_iterator begin()const { return _str; } const_iterator end()const { return _str _size; } //构造函数 string(const char* str)//常量字符串后面都有一个\0,如果写成\0就会有两个\0 { _size strlen(str); _capacity _size; _str new char[_capacity 1];//_capacity不包含\0,因此开空间的时候多开一个 strcpy(_str, str); } string(const string s)//拷贝构造 { _str new char[s._capacity1]; strcpy(_str, s._str); _size s._size; _capacity s._capacity; } ~string() { delete[]_str; _str nullptr; _size _capacity 0; } const char* c_str()const { return _str; } void clear()//清掉数据但不清空间 { _str[0] \0; _size 0; } char operator[](size_t pos) { assert(pos _size); return _str[pos]; } const char operator[](size_t pos)const { assert(pos _size); return _str[pos]; } size_t size()const { return _size; } size_t capacity()const { return _capacity; } void reserve(size_t n); void push_back(char ch); void append(const char* str); string operator(char ch); string operator(const char* str); void insert(size_t pos, char ch); void insert(size_t pos, const char* str); void erase(size_t pos, size_t len npos); size_t find(char ch, size_t pos0); size_t find(const char* str, size_t pos0); string substr(size_t pos, size_t lennpos ); string operator(const string s); private: char* _strnullptr; size_t _size0; size_t _capacity0; static const size_t npos; }; bool operator(const string s1, const string s2); bool operator(const string s1, const string s2); bool operator(const string s1, const string s2); bool operator(const string s1, const string s2); bool operator(const string s1, const string s2); bool operator!(const string s1, const string s2); ostream operator(ostream out,const string s); istream operator(istream in, string s); }string.cpp:#includestring.h namespace zwg { const size_t string::npos -1; void string::reserve(size_t n) { //手动扩容 if (n _capacity) { //开辟新空间拷贝数据释放旧空间指向新空间 char* tmp new char[n 1];//多开一个给\0 strcpy(tmp, _str); delete[] _str; _str tmp; _capacity n; } } //尾插字符 void string::push_back(char ch) { if (_size _capacity) { reserve(_capacity 0 ? 4 : 2 * _capacity); } _str[_size] ch; _size; _str[_size] \0;//不要漏了否则会乱码 } string string::operator(char ch) { push_back(ch); return *this; } //尾插字符串 void string::append(const char* str) { size_t len strlen(str); if (_size len _capacity) { reserve(_size len 2 * _capacity ? _size len : 2 * _capacity); } strcpy(_str _size, str);//strcpy会自动拷贝\0 _size len; } string string::operator(const char* str) { append(str); return *this; } //从pos位置插入字符 void string::insert(size_t pos, char ch) { assert(pos _size); if (_size _capacity)//需要扩容的情况 { reserve(_capacity 0 ? 4 : 2 * _capacity); } //挪动数据 size_t end _size1; while (end pos) { _str[end ] _str[end-1]; --end; } _str[pos] ch; _size; } //从pos位置插入字符串 void string::insert(size_t pos, const char* str) { assert(pos _size); size_t len strlen(str); if (len 0) return; if (_size len _capacity) { reserve(_size len 2 * _capacity ? _size len : 2 * _capacity); } //向后挪动数据 size_t end _size len; while (end poslen-1)//注意位置关系 { _str[end] _str[end - len]; --end; } //插入数据 for (size_t i 0; i len; i) { _str[pos i] str[i]; } _size len; } //删除从pos位置开始的len个字符 void string::erase(size_t pos, size_t len) { assert(pos _size); if (len _size-pos)//删除个数超过字符串的情况 { _str[pos] \0; _size pos; } else { for (size_t i poslen; i _size; i) { _str[i - len] _str[i];//数据前移 } _size - len; } } //查找字符 size_t string::find(char ch, size_t pos) { assert(pos _size); for (size_t i pos; i _size; i) { if (_str[i] ch) { return i; } } return npos; } //查找字符串 size_t string::find(const char* str, size_t pos) { assert(pos _size); const char* ptr strstr(_str pos, str);//采用strstr算法 if (ptr nullptr)//没找到的情况 { return npos; } else { return ptr - _str;//找到的位置减去起始位置的下标 } } //从pos位置开始取len个字符 string string::substr(size_t pos 0, size_t len ) { assert(pos _size); if (len _size - pos)//要求返回个数超过pos开始的个数有多少个返回多少个 { len _size - pos; } //返回一串字符 string sub; sub.reserve(len); for (size_t i 0; i len; i) { sub _str[pos i]; } return sub;//传值返回要写对应的拷贝构造 } //深拷贝 string string::operator(const string s) { if (this ! s)//防止自己赋值给自己出现问题 { delete[] _str;//释放旧空间 _str new char[s._capacity 1];//开辟新空间 strcpy(_str, s._str);//将数据拷贝到新空间 _size s._size; _capacity s._capacity; } return *this; } //比较大小(与库里面一样实现成全局函数) //实现两个就可以开始代码复用 bool operator(const string s1, const string s2) { return strcmp(s1.c_str(), s2.c_str()) 0; } bool operator(const string s1, const string s2) { return !(s1 s2); } bool operator(const string s1, const string s2) { return !(s1 s2); } bool operator(const string s1, const string s2) { return !(s1 s2); } bool operator(const string s1, const string s2) { return strcmp(s1.c_str(), s2.c_str())0; } bool operator!(const string s1, const string s2) { return !(s1 s2); } //重载流插入流提取运算符 ostream operator(ostream out, const string s) { for (auto ch : s) { out ch; } return out; } istream operator(istream in, string s) { s.clear(); const int N 256; char buff[N];//设一个缓冲,减少空间浪费 int i 0; //cin/scanf提取不到空格和换行符默认它们是分隔符。 //所以用get函数来规避这一问题。 char ch; ch in.get(); while (ch ! ch ! \n) { buff[i]ch; if (i N - 1) { buff[i] \0; s buff; i 0; } chin.get(); } if (i 0)//buff没存满的情况 { buff[i] \0; s buff; } return in; } }test.cpp:#includestring.h namespace zwg { void test_string1() { string s1; string s2(hello world); cout s1.c_str() endl; cout s2.c_str() endl; //下标遍历 for (size_t i 0; i s2.size(); i) { s2[i] 2; } cout s2.c_str() endl; //迭代器遍历 string::iterator it s2.begin(); while (it ! s2.end()) { *it 2; cout *it ; it; } cout endl; //范围for遍历 for (auto a : s2) { cout a ; } cout endl; } void test_string2() { string s1(hello world); s1 t; s1 $; cout s1.c_str() endl; s1 hello zwg; cout s1.c_str() endl; s1.insert(5, $); cout s1.c_str() endl; s1.insert(0, $); cout s1.c_str() endl; s1.insert(5, zwg); cout s1.c_str() endl; } void test_string3() { string s1(hello world); s1.erase(6, 50); cout s1.c_str() endl; string s2(hello world); s2.erase(6); cout s1.c_str() endl; string s3(hello world); s3.erase(6, 3); cout s3.c_str() endl; } void test_string4() { string s(test.cpp.zip); size_t pos s.find(.); string suffix s.substr(pos); cout suffix.c_str() endl; string copy(s);//拷贝构造copy cout copy.c_str() endl; ssuffix ; cout s.c_str() endl; } void test_string5() { string s1(hello world); string s2(hello world); cout (s1 s2) endl; cout (s1 s2) endl; //单参数构造函数支持隐式类型转换 cout (hello world s2) endl; cout (s1 hello world)endl; //cout (hello world hello world) endl;//err,运算符重载必须有一个类类型参数 cout s1 s2 endl; cin s1; cout s1 endl; } } int main() { zwg::test_string5(); return 0; }感谢各位观看如有不足请在评论区指点。