一、string 容器基本概念
C 风格字符串(以空字符结尾的字符数组)太过复杂难于掌握, 不适合大程序的开发, 所以 C++标准库定义了一种 string 类, 定义在头文件。
String 和 c 风格字串对比:
Char*是一个指针, String 是一个类
string 封装了 char, 管理这个字符串, 是一个 char 型的容器。
String 封装了很多实用的成员方法
查找 find, 拷贝 copy, 删除 delete 替换 replace, 插入 insert
不用考虑内存释放和越界:
string 管理 char*所分配的内存。 每一次 string 的复制, 取值都由 string 类负责维
护, 不用担心复制越界和取值越界等。 算法
二、string 容器常用操作(结构+ 🌰)
🌹 1、string的构造 和 赋值
string 构造函数
string();//创建一个空的字符串 例如: string str; string(const string& str);//使用一个 string 对象初始化另一个 string 对象 string(const char* s);//使用字符串 s 初始化 string(int n, char c);//使用 n 个字符 c 初始化 v
string 基本赋值操作
string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串 string& operator=(const string &s);//把字符串 s 赋给当前的字符串 string& operator=(char c);//字符赋值给当前的字符串 string& assign(const char *s);//把字符串 s 赋给当前的字符串 string& assign(const char *s, int n);//把字符串 s 的前 n 个字符赋给当前的字符串 string& assign(const string &s);//把字符串 s 赋给当前字符串 string& assign(int n, char c);//用 n 个字符 c 赋给当前字符串 string& assign(const string &s, int start, int n);//将 s 从 start 开始 n 个字符赋值给字符串
🌰
void test01() { //string(const char* s);//使用字符串s初始化 string str1("hello string"); cout << str1 << endl;//"hello string" //string(int n, char c);//使用n个字符c初始化 string str2(10, 'H'); cout << str2 << endl;//"HHHHHHHHHH" string str3 = str2; cout << str3 << endl;//"HHHHHHHHHH" string str4; //string& operator=(const string &s);//把字符串s赋给当前的字符串 str4 = str1; cout << str4 << endl;//"hello string" //string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串 string str5; str5 = "hello str5"; cout << str5 << endl;//"hello str5" //string& operator=(char c);//字符赋值给当前的字符串 string str6; str6 = 'H'; cout << str6 << endl;//"H" //string& assign(const char *s);//把字符串s赋给当前的字符串 string str7; str7.assign("hello str7"); cout << str7 << endl;//"hello str7" //string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串 string str8; str8.assign("hello str8", 5); cout << str8 << endl;//"hello" //string& assign(const string &s);//把字符串s赋给当前字符串 string str9; str9.assign(str8); cout << str9 << endl;//"hello" //string& assign(int n, char c);//用n个字符c赋给当前字符串 string str10; str10.assign(10, 'W'); cout << str10 << endl;//"WWWWWWWWWW" //string& assign(const string &s, int start, int n);//将s从start开始n个 string str11; str11.assign("hehehahahaxixi", 4, 6); cout << str11 << endl;//"hahaha" }
运行效果:
🍀2、string的字符的存取
char& operator[](int n);//通过[]方式取字符 char& at(int n);//通过 at 方法获取字符
🌰
void test02() { string str1 = "hello string"; cout << str1[1] << endl;//'e' cout << str1.at(1) << endl;//'e' str1[1] = 'E'; cout << str1 << endl;//"hEllo string" str1.at(7) = 'T'; cout << str1 << endl;//"hEllo sTring" }
运行效果:
[ ]和at的区别
void test03() { //[]和at的区别 string str1 = "hello string"; try { //str1[1000]='G';//越界 []不抛出异常 str1.at(1000) = 'G';//越界 at会抛出异常 } catch (exception& e) { cout << "异常:" << e.what() << endl; } }
🍁3、string 拼接操作
string& operator+=(const string& str);//重载+=操作符 string& operator+=(const char* str);//重载+=操作符 string& operator+=(const char c);//重载+=操作符 string& append(const char *s);//把字符串 s 连接到当前字符串结尾 string& append(const char *s, int n);//把字符串 s 的前 n 个字符连接到当前字符串结尾 string& append(const string &s);//同 operator+=() string& append(const string &s, int pos, int n);//把字符串 s 中从 pos 开始 //的 n 个字符连接到当前字符串结尾 string& append(int n, char c);//在当前字符串结尾添加 n 个字符 c
🌰
void test03() { string str1 = "hello"; string str2 = " string"; //string& operator+=(const string& str);//重载+=操作符 str1 += str2; cout << str1 << endl;//"hello string" string str3 = "hello"; //string& operator+=(const char* str);//重载+=操作符 str3 += " string"; cout << str3 << endl;//"hello string" string str4 = "hello"; //string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串结尾 str4.append("hehehaha", 4); cout << str4 << endl;//"hellohehe" //string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾 string str5 = "hello"; string str6 = "hehehahaha"; str5.append(str6, 4, 6); cout << str6 << endl;//"hellohahaha" }
运行效果:
🍂4、字符串的查找替换
int find(const string& str, int pos = 0) const; //查找 str 第一次出现位置,从 pos 开始查找 int find(const char* s, int pos = 0) const; //查找 s 第一次出现位置,从 pos开始查找 int find(const char* s, int pos, int n) const; //从 pos 位置查找 s 的前 n 个字符第一次位置 int find(const char c, int pos = 0) const; //查找字符 c 第一次出现位置 int rfind(const string& str, int pos = npos) const;//查找 str 最后一次位置,从 pos 开始查找 int rfind(const char* s, int pos = npos) const;//查找 s 最后一次出现位置,从pos 开始查找 int rfind(const char* s, int pos, int n) const;//从 pos 查找 s 的前 n 个字符最后一次位置 int rfind(const char c, int pos = 0) const; //查找字符 c 最后一次出现位置 string& replace(int pos, int n, const string& str); //替换从 pos 开始 n 个字符为字符串 str string& replace(int pos, int n, const char* s); //替换从 pos 开始的 n 个字符为字符串 s
🌰
void test04() { //int find(const string& str, int pos = 0) const; //查找str第一次出现位置, 从pos开始查找 string str1 = "hehe:haha:xixi:haha:heihei"; //从str1中找haha string tmp = "haha"; cout << str1.find(tmp) << endl;//5 cout << str1.find(tmp, 10) << endl;//15 //int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找 cout << str1.find("haha") << endl;//527 str1.replace(5, 4, "###"); cout << str1 << endl;//"hehe:###:xixi:haha:heihei" string str2 = "www.sex.117114.sex.person.77.com"; //需求:将字符串中的所有"sex"用***屏蔽 int ret = 0; while ((ret = str2.find("sex")) < str2.size()) { str2.replace(ret, strlen("sex"), "***"); } cout << str2 << endl; }
运行效果:
🍃5、string 比较操作
/* compare 函数在>时返回 1, <时返回 -1, ==时返回 0。 比较区分大小写, 比较时参考字典顺序, 排越前面的越小。大写的 A 比小写的 a 小。 */ int compare(const string &s) const;//与字符串 s 比较 int compare(const char *s) const;//与字符串 s 比较
🌰
void test05() { string str1 = "hehe"; string str2 = "haha"; cout << str1.compare(str2) << endl;//1 cout << str1.compare("lala") << endl;//‐1 cout << str1.compare("hehe") << endl;//0 }
运行效果:
🌷6、字符串提取
string substr(int pos = 0, int n = npos) const;//返回由 pos 开始的 n 个字符组成的字符串
🌰
void test06() { string str1 = "hehehe:ha:xixixi:lalala:heihei"; //cout<<str1.substr(5,4)<<endl; //案例:将:分割的所有字符串提取出来 int pos = 0; while (1) { int ret = str1.find(":", pos); if (ret < 0) { string tmp = str1.substr(pos, str1.size()-pos); cout << tmp << endl; break; } string tmp = str1.substr(pos, ret-pos); cout << tmp << endl; pos = ret + 1; } }
这里特别解释一下为啥当ret<0时作为退出条件,因为当find没找到是他会默认找到最后面,也就是一长串的1。通过二进制转换后发现最后的结果为-1!
运行效果:
🌸7、字符串的插入删除
string& insert(int pos, const char* s); //插入字符串 string& insert(int pos, const string& str); //插入字符串 string& insert(int pos, int n, char c);//在指定位置插入 n 个字符 c string& erase(int pos, int n = npos);//删除从 Pos 开始的 n 个字符
🌰
void test07() { string str1 = "hello world"; str1.insert(5, "hehe"); cout << str1 << endl;//"hellohehe world str1.erase(5, 4);//删除字符串中hehe cout << str1 << endl;//"hello world" //清空字符串 str1.size()得到字符串的总大小 str1.erase(0, str1.size()); cout << str1.size() << endl;//0 }
运行效果:
💮8、string 和C风格的字符串转换
在 c++中存在一个从 const char 到 string 的隐式类型转换, 却不存在从一个 string
对象到 Cstring 的自动类型转换。 对于 string 类型的字符串, 可以通过 cstr()函数返回 string 对象对应的 C_string. 通常, 程序员在整个程序中应坚持使用 string 类对象, 直到必须将内容转化为 char 时才将其转换为 C_string。
提示: 为了修改 string 字符串的内容, 下标操作符[]和 at 都会返回字符的引用。
但当字符串的内存被重新分配之后, 可能发生错误。
//string 转 char* string str = "itcast"; const char* cstr = str.c_str(); //char* 转 string char* s = "itcast"; string str(s);
🌰
void test08() { char str2[] = "hello str"; //将char * 转成 string (直接完成) string str1(str2); cout << str1 << endl;//hello str string str3 = "hello str3"; //不能直接将string 转换成 char * 必须借助string中的c_str方法完成 //char *str4 = str3;//err char* str4 = const_cast<char*> (str3.c_str()); cout << str4 << endl;//"hello str3" }
运行效果:
感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!