☰
string类相关接口的使用及模拟实现
2026/10/18 4:48:25 网站建设 项目流程

一.标准库中的string类

1.1

std::string是c++标准库中最常用的字符串处理工具,位于std命名空间下,本质是basic_string<char>的一个特化别名,用于可变长的字符序列,并自动管理底层的动态内存。在底层string通常使用动态数组来管理字符序列,并且以\0结尾,当字符串较短时,字符数据会直接存储在对象本地的栈内存中,无需进行堆内存分配,极大提升了短字符串的性能,当字符超过当前容量时,string会在堆上申请更大的内存块,将旧数据拷贝过去,并释放旧内存,即自动扩容,但这自动扩容会有一定的程序性能消耗,如果提前知道多大空间,提前开好一定空间,就可以尽可能减少性能的损耗。对于string类的常见接口有

1.构造与初始化

2.容量与大小操作

3.元素访问与遍历

4.修改操作

5.查找

6.与c风格的字符交互

1.2

auto是一个类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得,也就是说auto可以推导类型,但auto的使用仍然有一些注意事项:

1.用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

2.当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际 只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

3.auto不能作为函数的参数(c++11不支持,但c++20开始支持),可以做返回值,但是建议谨慎使用,例如:auto ret = func1();虽然支持这种写法,但需要查找就比较麻烦。

4.auto不能直接用来声明数组

5.类型包含"auto"符号必须具有初始值设定项

auto的出现相当于一个语法糖,在某些代码场景当中,可以简化代码:

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<string.h> #include<map> using namespace std; int main() { std::map<std::string, std::string> dict = { {"apple","苹果"},{"orange","橙子"},{"pear","梨"} }; //std::map<std::string, std::string>::iterator it = dict.begin(); //auto语法糖效果 auto it = dict.begin(); while(it != dict.end()) { cout << it->first << ":" << it->second << endl; ++it; } return 0; }

map容器:自带索引,查找速度极快,底层通常是哈希表或者红黑树,it->first,it->second为键对值,iterator为迭代器,可以粗略理解成一个比较智能的指针,这里说到迭代器,迭代器一共有四种:

1.正向迭代器,可读可写,支持从字符向尾部进行正向遍历,且对指向的字符拥有读写权限,本质上在string模型中封装了字符指针的类对象,函数重载了*,++,--,+n(随机访问)等运算符。获取方式为s.begin(),s.end();

2.常量正向迭代器,同样支持正向遍历,但底层封装的是comst修饰的常量字符串,只有可读的权限,通过s.cbegin(),s.cend()显示获取,或者当string对象被const修饰时,调用s.begin()也会自动退化成const_iterator。

3.反向迭代器,支持从字符尾部向头部进行反向遍历,且对指向的字符拥有读写权限,底层是一个适配器,封装了一个正向迭代器,++通常底层调用封装的正向迭代器--,*解引用时也会做偏移处理,以保证取到正确的字符。获取方式:s.rbegin(),s.rend();

4.常量反向迭代器,支持反向遍历,只有读权限,没有写权限,底层封装的是const相关的正向迭代器,既限制写操作,又实现了反向移动。获取方式:s.rbegin(),s.crend,当string对象本身被const修饰时,调用s.rbegin会自动退化成const_reverse_iterator。

string迭代器属于随机访问迭代器,底层是连续字符数组,不仅支持++,--,还支持it+n,it-n,it1-it2等指针算术运算,时间复杂度为O(1)。

范围for分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。范围for可以作用到数组和容器对象上进行遍历 范围for的底层很简单,容器遍历实际就是替换为迭代器。取出数据放入变量中,中间是一个拷贝赋值,产生临时变量,不影响原数据。

#define _CRT_SECURE_NO_WARNINGS 1 #include<string.h> #include<map> #include<iostream> using namespace std; int main() { int arr[] = { 1,2,3,4,5,6,7,8,9 }; for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) { arr[i] *= 2; } for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) { cout << arr[i] << " "; } cout << endl; //c++11的遍历 for (auto& e:arr) { e *= 2; } for (auto e : arr) { cout << e << " "; } return 0; }

在模拟实现string当中,如果我们写了一个命名空间A,在A里面写了范围for,并且模拟实现begin(),将begin改了名字,比如说改成Begin(),编译器会报错,虽然我将代码放到A命名空间与标准库进行隔离,但这只是区分隔离符号,范围for底层只认识begin(),end()。如果没有展开命名空间std,报错会比较简短,直接报错找不到begin()函数,如果展开命名空间,那么编译器就会将std::begin暴露在全局域,放在候选集合里,而全局begin是一个模板:

template<typename T> auto begin(T& t) -> decltype(t.begin()){ return t.begin(); //这里尝试调用 t.begin(),类只有Begin(),没有begin() }

现在要用这个bit::string去实例化模板,但现在没有类里面找到begin(),所以就会报一大堆错误,那一大堆就是模板的实例化调用链路回溯。命名空间只能隔离类名符号,不能改变语法规则。

二.string类的常用接口

1.string类的常见构造

2.string类对象的访问及遍历操作

operator[]对于普通的string类对象,可读可写,但对于const修饰的对象只有可读权限,没有写的权限:

// 普通string,可读可写 char& operator[](size_t pos); // const修饰的string对象,只读,不能修改字符 const char& operator[](size_t pos) const;

operator不做越界检查,如果pos>s.size,程序可能会崩溃。

范围for底层也是用迭代器实现的,相当于一个语法糖,数组也支持范围for遍历,string、vector,可以用迭代器遍历,也可以用[],用[]效率会更高,但list容器用迭代器比用[]重载效率更高。

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; int main1() { string s = "hello"; cout << s[0]; // h s[1] = 'E'; // 修改第1位字符,s变成 hEllo const string cs = "world"; cout << cs[2]; // r // cs[2] = 'a'; // 编译报错,const版本返回常量引用,禁止写 return 0; } int main() { string s1("hello world"); //operator[]遍历 cout << "[]遍历:" << s1 << endl; //operator修改 s1[0] = 'H'; cout << "修改后:" << s1 << endl; //正向迭代器遍历 cout << "正向迭代器遍历:"; string::iterator it1 = s1.begin(); while (it1!=s1.end()) { cout << *it1; ++it1; } cout << endl; //反向迭代器遍历 cout << "反向迭代器遍历:"; string::reverse_iterator it2 = s1.rbegin(); while (it2!=s1.rend()) { cout << *it2; ++it2; } cout << endl; //范围for遍历 cout << "范围for遍历:"; for (char ch :s1) { cout << ch; } cout << endl; return 0; }

3.striing类对象的容量操作

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<string> using namespace std; int main() { //size是有效数据个数,capacity是容量大小 string s("hello world"); cout << s.size() << endl; cout << s.capacity() << endl; //empty判断是否为空 if (s.empty()) { cout << "该字符串为空" << endl; } else { cout << "该字符串不为空" << endl; } //reserve为字符串预留空间,只预分配底层空间大小,不改变字符有效数据个数 //提前开,避免过度扩容增加性能消耗 s.reserve(100);// >capacity,有效数据个数为11不改变,底层空间容量大小改变 cout << s.size() << endl; cout << s.capacity() << endl; s.reserve(11); // >size,<capacity,不做任何改变,不缩容 cout << s.size() << endl; cout << s.capacity() << endl; s.reserve(3);// <size,忽略,不缩容,也不截断字符 cout << s.size() << endl; cout << s.capacity() << endl; s.resize(8, 'h');//修改有效字符数量size,会填充/截断字符,会影响容量 cout << "\nresize(8,'!')后:" << s << endl; cout << "size = " << s.size() << endl; // 6. clear():清空有效字符,size变为0;**不会释放底层capacity容量** s.clear(); cout << "\nclear()之后:" << endl; cout << "字符串内容:" << s << endl; cout << "size = " << s.size() << endl; cout << "capacity = " << s.capacity() << endl; // 容量保持不变,内存没有归还 return 0; }

4.string类对象的修改操作

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; int main() { string s("hello world"); cout << "原始字符串:" << s << endl; s.push_back('!'); cout << "新的字符串:" << s << endl; s.append("xxxxxxx"); cout << "追加后新的字符串:" << s << endl; //operator+=重载,可以追加字符串/字符 s.operator+=("~"); cout << "+=后新的字符串:" << s << endl; //c_str返回c风格的const char*字符串,末尾自带\0 const char* cstr = s.c_str(); cout << "返回后的字符串:" << cstr << endl; //find+npos 从pos位置开始找,找到了返回下标,找不到返回std::npos string str = "abcdeabc"; size_t pos1 = str.find('a', 0); cout << "\nstr.find('a',0) 找到位置:" << pos1 << endl; // 0 size_t pos_not = str.find('z'); // 不存在字符z if (pos_not == string::npos) { cout << "find没找到,返回npos" << endl; } // 6. rfind:从pos位置[向前]查找(反向查找) size_t pos2 = str.rfind('a'); // 从末尾向前找'a' cout << "str.rfind('a')反向查找a的位置:" << pos2 << endl; //5 // 7. substr:从pos位置,截取n个字符,返回新字符串 string sub = str.substr(2, 3); // 下标2开始,取3个字符 cout << "str.substr(2,3)截取结果:" << sub << endl; // cde return 0; }

5.string类的非成员函数

#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <string> using namespace std; int main() { //1. operator+ 字符串拼接(尽量少用) string s1 = "hello"; string s2 = " world"; string s3 = s1 + s2; // operator+ 重载,生成新string对象 cout << "s1 + s2 = " << s3 << endl; /* 缺点:operator+ 会创建临时对象,值返回,触发深拷贝,效率低。 推荐优先用 += 原地追加,不产生临时对象 */ // 2. operator>> 输入运算符重载(重点) string inStr ; cout << "\n请输入不带空格的字符串:"; cin >> inStr; // operator>> ,遇到【空格/回车】就停止读取 cout << "cin >> 读取结果:" << inStr << endl; // 3. operator<< 输出运算符重载(重点) cout << "operator<<直接输出string:" << inStr << endl; // cout << 就是调用 string 的 operator<< 重载,直接打印字符串内容 // 4. getline 获取一行字符串(重点) string line ; // 注意:如果前面用了cin >>,缓冲区会残留换行符,getline会读到空串 cin .ignore(); // 吃掉缓冲区遗留的换行 cout << "\n请输入一整行(可以带空格):"; getline(cin, line); // 读取一整行,直到回车为止,保留中间空格 cout << "getline读取一行:" << line << endl; // 5. relational operators 关系比较运算符(重点) string a = "apple"; string b = "banana"; cout << "\n====字符串比较(按ASCII码逐字符对比)====" << endl; if (a < b) { cout << a << " < " << b << endl; } if (a != b) { cout << a << " != " << b << endl; } if (a == "apple") { cout << a << " == \"apple\"" << endl; } if ("app" < a) { cout << "\"app\" < " << a << endl; } return 0; }

三.string类的模拟实现

string.h

#define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<iostream> #include<assert.h> using namespace std; namespace bit { class string { public: //typedef char* iterator; using iterator = char*; using const_iterator = const char*; //string(); string(const char* str = ""); string(const string& s); string& operator=(const string& s); ~string(); 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 pos = 0); size_t find(const char* str, size_t pos = 0); char& operator[](size_t i) { assert(i < _size); return _str[i]; } const char& operator[](size_t i) const { assert(i < _size); return _str[i]; } iterator begin() { return _str; } iterator end() { return _str+_size; } const_iterator begin() const { return _str; } const_iterator end() const { return _str + _size; } size_t size() const { return _size; } const char* c_str() const { return _str; } void clear() { _str[0] = '\0'; _size = 0; } string substr(size_t pos, size_t len = npos); private: char* _str = nullptr; size_t _size = 0; size_t _capacity = 0; public: // ⴦ //static const size_t npos = -1; static const size_t npos; }; bool operator== (const string& lhs, const string& rhs); bool operator!= (const string& lhs, const string& rhs); bool operator> (const string& lhs, const string& rhs); bool operator< (const string& lhs, const string& rhs); bool operator>= (const string& lhs, const string& rhs); bool operator<= (const string& lhs, const string& rhs); ostream& operator<<(ostream& os, const string& str); istream& operator>>(istream& is, string& str); }

string.cpp

#include"string.h" namespace bit { const size_t string::npos = -1; // 11:52 /*string::string() :_str(new char[1]{ '\0' }) , _size(0) , _capacity(0) {}*/ string::string(const char* str) :_size(strlen(str)) { _capacity = _size; _str = new char[_size + 1]; strcpy(_str, str); } // s2(s1) string::string(const string& s) { _str = new char[s._capacity + 1]; strcpy(_str, s._str); _size = s._size; _capacity = s._capacity; } // s2 = s1 = s3 // s1 = s1; 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; } string::~string() { delete[] _str; _str = nullptr; _size = 0; _capacity = 0; } void string::reserve(size_t n) { if (n > _capacity) { char* tmp = new char[n + 1]; strcpy(tmp, _str); delete[] _str; _str = tmp; _capacity = n; } } void string::push_back(char ch) { /*if (_size == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } _str[_size] = ch; _size++;*/ insert(_size, ch); } void string::append(const char* str) { //size_t len = strlen(str); //if (_size + len > _capacity) //{ // size_t newCapacity = 2 * _capacity; // // 扩2倍不够,则需要多少扩多少 // if (newCapacity < _size + len) // newCapacity = _size + len; // reserve(newCapacity); //} //strcpy(_str + _size, str); //_size += len; insert(_size, str); } string& string::operator+=(char ch) { push_back(ch); return *this; } string& string::operator+=(const char* str) { append(str); return *this; } void string::insert(size_t pos, char ch) { assert(pos <= _size); if (_size == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } /*int end = _size; while (end >= (int)pos) { _str[end + 1] = _str[end]; --end; }*/ size_t end = _size + 1; while (end > pos) { _str[end] = _str[end - 1]; --end; } _str[pos] = ch; _size++; } void string::insert(size_t pos, const char* str) { assert(pos <= _size); size_t len = strlen(str); if (_size + len > _capacity) { size_t newCapacity = 2 * _capacity; // 扩2倍不够,则需要多少扩多少 if (newCapacity < _size + len) newCapacity = _size + len; reserve(newCapacity); } /*int end = _size; while (end >= (int)pos) { _str[end + len] = _str[end]; --end; }*/ size_t end = _size + len; while (end > pos + len - 1) { _str[end] = _str[end - len]; --end; } for (size_t i = 0; i < len; i++) { _str[pos + i] = str[i]; } _size += len; } void string::erase(size_t pos, size_t len) { assert(pos < _size); if (len >= _size - pos) { _str[pos] = '\0'; _size = pos; } else { // 从后往前挪 size_t end = pos + len; while (end <= _size) { _str[end - len] = _str[end]; ++end; } _size -= len; } } size_t string::find(char ch, size_t pos) { assert(pos < _size); for (size_t i = pos; i < _size; i++) { if (ch == _str[i]) return i; } return npos; } size_t string::find(const char* str, size_t pos) { assert(pos < _size); const char* ptr = strstr(_str + pos, str); if (ptr == nullptr) { return npos; } else { return ptr - _str; } } string string::substr(size_t pos, size_t len) { assert(pos < _size); // 大于后面剩余串的长度,则直接取到结尾 if (len > (_size - pos)) { len = _size - pos; } bit::string sub; sub.reserve(len); for (size_t i = 0; i < len; i++) { sub += _str[pos + i]; } //cout << sub.c_str() << endl; return sub; } bool operator== (const string& lhs, const string& rhs) { return strcmp(lhs.c_str(), rhs.c_str()) == 0; } bool operator!= (const string& lhs, const string& rhs) { return !(lhs == rhs); } bool operator> (const string& lhs, const string& rhs) { return !(lhs <= rhs); } bool operator< (const string& lhs, const string& rhs) { return strcmp(lhs.c_str(), rhs.c_str()) < 0; } bool operator>= (const string& lhs, const string& rhs) { return !(lhs < rhs); } bool operator<= (const string& lhs, const string& rhs) { return lhs < rhs || lhs == rhs; } ostream& operator<<(ostream& os, const string& str) { //os<<'"'; //os << "xx\"xx"; for (size_t i = 0; i < str.size(); i++) { //os << str[i]; os << str[i]; } //os << '"'; return os; } istream& operator>>(istream& is, string& str) { str.clear(); char ch; //is >> ch; ch = is.get(); while (ch != ' ' && ch != '\n') { str += ch; ch = is.get(); } return is; } }

test.cpp

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<string> #include<list> #include<map> using namespace std; //class string //{ //public: // char& operator[] (size_t pos) // { // assert(pos < _size); // return _str[pos]; // } //private: // //char buff[16]; // char* _str; // size_t _size; // size_t _capacity; //}; // C++20开始支持 //void func1(auto x); //auto func3() //{ // auto y = func4(); // return y; //} // //auto func2() //{ // auto x = func3(); // //... // return x; //} //int main() //{ // //auto ret1 = func2(); // string s1("hello world"); // // // 下标+[] // for (size_t i = 0; i < s1.size(); i++) // { // s1[i]++; // } // // for (size_t i = 0; i < s1.size(); i++) // { // cout << s1[i] << " "; // } // cout << endl; // // // 迭代器 -- 像指针一样的对象 // string::iterator it1 = s1.begin(); // while (it1 != s1.end()) // { // (*it1)--; // // ++it1; // } // cout << endl; // // it1 = s1.begin(); // while (it1 != s1.end()) // { // cout << *it1 << " "; // ++it1; // } // cout << endl; // // list<int> lt; // lt.push_back(1); // lt.push_back(2); // lt.push_back(3); // lt.push_back(4); // // int i = 0; // int j = i; // // 自动推导类型 C++11 // auto z = i; // int // auto x = 1.1; // double // auto p = &i; // int* // int& r1 = i; // auto r2 = r1; // int // auto& r3 = r1; // int& // //auto r4; // 报错 // // //list<int>::iterator it = lt.begin(); // auto it = lt.begin(); // while (it != lt.end()) // { // cout << *it << " "; // ++it; // } // cout << endl; // // // auto语法糖 // // 简化代码,替代写起来长的类型 // std::map<std::string, std::string> dict; // //std::map<std::string, std::string>::iterator dit = dict.begin(); // auto dit = dict.begin(); // // // 范围for C++11 语法糖 // // 适用于容器遍历和数组遍历 // // 自动取容器的数据赋值给左边的对象 // // 自动++,自动判断结束 // // 原理:范围for底层是迭代器 // // //for (char ch : s1) // for (auto ch : s1) // { // cout << ch << " "; // } // cout << endl; // // // 修改 // for (auto& ch : s1) // { // ch++; // } // // for (auto ch : s1) // { // cout << ch << " "; // } // cout << endl; // // for (auto e : lt) // { // cout << e << " "; // } // cout << endl; // // int a[] = { 1,2,3,4,5,6 }; // for (size_t i = 0; i < sizeof(a)/sizeof(int); i++) // { // cout << a[i] << " "; // } // cout << endl; // // for (auto e : a) // { // cout << e << " "; // } // cout << endl; // // return 0; //} //int main() //{ // string s1("hello world"); // string::reverse_iterator rit = s1.rbegin(); // while (rit != s1.rend()) // { // cout << *rit << " "; // ++rit; // } // cout << endl; // // const string s2(s1); // //string::const_iterator it1 = s2.begin(); // auto it1 = s2.begin(); // while (it1 != s2.end()) // { // //*it1 += 1; // cout << *it1 << " "; // ++it1; // } // cout << endl; // // //string::const_reverse_iterator rit1 = s2.rbegin(); // auto rit1 = s2.rbegin(); // while (rit1 != s2.rend()) // { // cout << *rit1 << " "; // ++rit1; // } // cout << endl; // // return 0; //} //int main() //{ // try // { // string s1("hello world11111"); // cout << s1.size() << endl; // cout << s1.length() << endl; // cout << s1.max_size() << endl; // cout << s1.capacity() << endl; // cout << endl << endl; // // s1.clear(); // cout << s1.size() << endl; // cout << s1.capacity() << endl; // // //s1[20]; // // s1.at(20); // } // catch (const exception& e) // { // cout << e.what() << endl; // } // // return 0; //} //int main() //{ // string s1("hello"); // s1.push_back(','); // s1.push_back('w'); // cout << s1 << endl; // // s1.append("orld"); // cout << s1 << endl; // // s1.append(10, '!'); // cout << s1 << endl; // // string s2("hello bit hello world"); // // s1.append(s2.begin()+6, s2.end()); // cout << s1 << endl; // // string s3("hello"); // s3 += ','; // s3 += "world"; // cout << s3 << endl; // // return 0; //} // reserve 保留 预留 // reverse 反向 翻转 //int main() //{ // string s1; // // 提前开空间,避免扩容 // s1.reserve(200); // // size_t old = s1.capacity(); // cout << "capacity:" << old << endl; // for (size_t i = 0; i < 200; i++) // { // s1 += 'x'; // if (s1.capacity() != old) // { // cout << "capacity:" << s1.capacity() << endl; // old = s1.capacity(); // } // } // // string s3("11111111"); // string s4("111111112222222222222222222222222222222222222222222"); // cout << sizeof(s3) << endl; // // return 0; //} //int main() //{ // string s1("11111111111111111111"); // cout << s1 << endl; // cout << s1.size() << endl; // cout << s1.capacity() << endl; // // // 删除 // // n < size // s1.resize(15); // cout << s1 << endl; // cout << s1.size() << endl; // cout << s1.capacity() << endl; // // // 插入 // // size < n < capacity // s1.resize(25, 'x'); // cout << s1 << endl; // cout << s1.size() << endl; // cout << s1.capacity() << endl; // // // n > capacity // s1.resize(40, 'x'); // cout << s1 << endl; // cout << s1.size() << endl; // cout << s1.capacity() << endl; // // return 0; //} //int main() //{ // string s1("hello world"); // s1.insert(5, "xxxx"); // cout << s1 << endl; // // s1.erase(5, 5); // cout << s1 << endl; // // s1.erase(0, 1); // cout << s1 << endl; // // s1.erase(s1.begin()); // cout << s1 << endl; // // s1.erase(5, 10); // cout << s1 << endl; // // return 0; //} //int main() //{ // string s1("hello world hello bit"); // cout << s1 << endl; // /*size_t i = s1.find(' '); // while (i != string::npos) // { // s1.replace(i, 1, "%%"); // i = s1.find(' ', i+2); // } // cout << s1 << endl;*/ // // string s2; // for (auto ch : s1) // { // if (ch != ' ') // s2 += ch; // else // s2 += "%%"; // } // cout << s2 << endl; // //s1.swap(s2); // // // return 0; //} //int main() //{ // string s1("hello world"); // cout << s1 << endl; // cout << s1.c_str() << endl; // // /*string s2("Test.cpp"); // FILE* fout = fopen(s2.c_str(), "r"); // char ch = fgetc(fout); // while (ch != EOF) // { // cout << ch; // ch = fgetc(fout); // }*/ // // /*const char* p1 = "xxxxx"; // int* p2 = nullptr; // cout << (void*)p1 << endl; // cout << p2 << endl;*/ // // string s3("test.cpp.zip"); // size_t pos = s3.rfind('.'); // if (pos != string::npos) // { // string sub = s3.substr(pos); // cout << sub << endl; // } // // // // std::string str("Please, replace the vowels in this sentence by asterisks."); // std::size_t found = str.find_first_not_of("aeiou"); // while (found != std::string::npos) // { // str[found] = '*'; // found = str.find_first_not_of("aeiou", found + 1); // } // // std::cout << str << '\n'; // // return 0; //} #include <iostream> #include <string> using namespace std; //int main() //{ // string str; // //cin >> str; // //getline(cin, str, '#'); // getline(cin, str); // // size_t pos = str.rfind(' '); // cout << str.size() - (pos + 1) << endl; // // return 0; //} //int main() //{ // string s3 = to_string(11.11); // // string s1, s2; // cin >> s1 >> s2; // cout << s1 << endl; // cout << s2 << endl; // // return 0; //} ////////////////////////////////////////////////////////////////// #include"string.h" void test_string1() { bit::string s2; cout << s2.c_str() << endl; bit::string s1("hello world"); cout << s1.c_str() << endl; s1[0] = 'x'; cout << s1.c_str() << endl; for (size_t i = 0; i < s1.size(); i++) { cout << s1[i] << " "; } cout << endl; // 迭代器 -- 像指针一样的对象 bit::string::iterator it1 = s1.begin(); while (it1 != s1.end()) { (*it1)--; ++it1; } cout << endl; it1 = s1.begin(); while (it1 != s1.end()) { cout << *it1 << " "; ++it1; } cout << endl; // 修改 // 底层是迭代器的支持 // 意味着支持迭代器就支持范围for for (auto& ch : s1) { ch++; } for (auto ch : s1) { cout << ch << " "; } cout << endl; const bit::string s3("xxxxxxxxx"); for (auto& ch : s3) { //ch++; cout << ch << " "; } cout << endl; } void test_string2() { bit::string s1("hello world"); cout << s1.c_str() << endl; s1 += '#'; s1 += "#hello world"; cout << s1.c_str() << endl; bit::string s2("hello world"); cout << s2.c_str() << endl; s2.insert(6, 'x'); cout << s2.c_str() << endl; s2.insert(0, 'x'); cout << s2.c_str() << endl; bit::string s3("hello world"); cout << s3.c_str() << endl; s3.insert(6, "xxx"); cout << s3.c_str() << endl; s3.insert(0, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); cout << s3.c_str() << endl; } void test_string3() { bit::string s1("hello world"); cout << s1.c_str() << endl; s1.erase(6, 2); cout << s1.c_str() << endl; s1.erase(5, 20); cout << s1.c_str() << endl; s1.erase(3); cout << s1.c_str() << endl; } void test_string4() { bit::string s1("hello world"); cout << s1.find(' ') << endl; cout << s1.find("wo") << endl; bit::string s2 = "https://legacy.cplusplus.com/reference/cstring/strstr/?kw=strstr"; //bit::string s2 = "https://blog.csdn.net/ww753951/article/details/130427526"; size_t pos1 = s2.find(':'); size_t pos2 = s2.find('/', pos1+3); if (pos1 != string::npos && pos2 != string::npos) { bit::string domain = s2.substr(pos1 + 3, pos2 - (pos1 + 3)); cout << domain.c_str() << endl; bit::string uri = s2.substr(pos2+1); cout << uri.c_str() << endl; } } void test_string5() { bit::string s1("hello world"); bit::string s2(s1); cout << s1.c_str() << endl; cout << s2.c_str() << endl; s1[0] = 'x'; cout << s1.c_str() << endl; cout << s2.c_str() << endl; bit::string s3("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); s1 = s3; cout << s1.c_str() << endl; cout << s3.c_str() << endl; s1 = s1; cout << s1.c_str() << endl; } void test_string6() { bit::string s1("hello world"); bit::string s2(s1); bit::string s3 = s1; // 构造+拷贝 ->优化直接构造 bit::string s4 = "hello world"; cout << (s1 == s2) << endl; cout << (s1 < s2) << endl; cout << (s1 > s2) << endl; cout << (s1 == "hello world") << endl; cout << ("hello world" == s1) << endl; //operator<<(cout, s1); cout << s1 << endl; cin >> s1; cout << s1 << endl; std::string ss1("hello world"); cin >> ss1; cout << ss1 << endl; } int main() { test_string6(); return 0; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询