String字符串容器
C 风格字符串(以空字符结尾的字符数组)太过复杂难于掌握,不适合大程序的开发, 所以 C++标准库定义了一种 string 类,定义在头文件。
#include <string>
String 和 c 风格字符串对比:
Char*是一个指针,String 是一个类,系统为我们封装了方法,来存储和管理字符串。
string容器的使用
具体作用以及运行结果已在代码中注释,感觉这样大佬们观看能更加简单明了
目录
初始化(构造函数使用)
string(); | 创建一个空的字符串 例如: string str; |
string(const string& str); | 使用一个 string 对象初始化另一个 string 对象 |
string(const char* s); | 使用字符串 s 初始化 |
string(int n, char c); | 使用 n 个字符 c 初始化 |
void test_01()
{
//1. string(const char* s); 使用字符串 s 初始化
string str1("hello");
cout<<str1<<endl; //hello
//2. string(int n, char c); 使用 n 个字符 c 初始化
string str2(5,'h'); //将str2字符串中存储5个'h'
cout<<str2<<endl; //hhhhh
//string();创建一个空的字符串 例如: string str;
string str3;
cout<<str3.size()<<endl; //0 初始化大小为0
str3 = "hello";
cout<<str3.size()<<endl; //5 大小为5 获取的大小不包含'\0'
}
基本赋值操作
string& operator=(const char* s); | char*类型字符串 赋值给当前的字符串 |
string& operator=(const string &s); | 把字符串 s 赋给当前的字符串 |
string& assign(const char *s); | 把字符串 s 赋给当前的字符串 |
string& assign(const char *s, int n); | 把字符串 s 的前 n 个字符赋给当前的字 |
string& assign(const string &s, int start, int n); | 将 s 从 start 开始 n 个 字符赋值给字符串 |
void test_01()
{
//系统在类中还重载了赋值操作符(=)
str2 = str1;
cout<<str2<<endl; //hello
string str4;
str4.assign("aaaaaaaa",3); //将形参的字符串前三个赋值给str4
cout<<str4<<endl; //aaa
string str6 = "helloworld";
string str7;
str7.assign(str6,2,3); //将str6字符串从下标为2开始向后的3个字符 赋值给str7
cout<<str7<<endl; //llo
}
访问和存取单个字符(at)
char& operator[](int n); | 通过[]方式取字符 |
char& at(int n); | 通过 at 方法获取字符 |
void test_01()
{
string str1 = "abcdefg";
//使用下标获得并更改字符
str1[2] = 'C';
str1.at(5) = 'F';
cout<<str1<<endl; //abCdeFg
try{
//str1[1000] = 'A'; //使用数组取值的方式不会抛出异常
str1.at(1000) = 'A'; //at会抛出异常 可以使用exception捕获
}catch(exception &ex){
cout<<ex.what()<<endl;
}
cout<<str1[3]<<"--"<<str1.at(5)<<endl;
cout<<"执行到最后"<<endl;
}
字符串拼接(append)
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 个字符连接到当前字符串结尾 |
void test_01()
{
//1. string& operator+=(const char* str); 重载+=操作符
string str1 = "hello";
string str2 = str1 + " world";
cout<<str2<<endl; //hello world
//2. string& operator+=(const string& str); 重载+=操作符
string str3 = str2 + str1;
cout<<str3<<endl; //hello worldhello
str1 += " world";
cout<<str1<<endl; //hello world
//3. string& append(const char *s, int n); 把字符串 s 的前 n 个字符连接到当前字符串结尾
string str4 = "hello";
string str5;
str5.append("hello",3); //从下标0开始 向后获取三个元素
cout<<str5<<endl; //hel
//4. string& append(const char *s, int n); 把字符串 s 的前 n 个字符连接到当前字符串结尾
string str6;
str6.append(str4,2,4); //从下标为2的数据开始 向后获取到下标为4的元素
cout<<str6<<endl; //llo
}
查找与替换(find replace)
包含案例(自主完成案例)
案例 将路径中的sex替换成*** (www.sex.666.sex.777.sex.com)
int find(const string& str, int pos = 0) const; | 查找 str 第一次出现位置, 从 pos 开始查找 |
int find(const char* s, int pos, int n) const; | 从 pos 位置查找 s 的前 n 个字符第一次位置(char*位置也可用string) |
int rfind(const string& str, int pos = npos) const; | 查找 str 最后一次位 置,从 pos 开始查找 |
string& replace(int pos, int n, const string& str); | 替换从 pos 开始 n 个 字符为字符串 str |
void test_01()
{
//1. int find(const string& str, int pos = 0) const;
//查找 str 第一次出现位置, 从 pos 开始查找 默认值为0
string str1 = "haha:hehe:xixi";
string str2 = "hehe";
int ret = str1.find(str2); //查找字符 并返回下标位置
cout<<ret<<endl; //5 返回str1中于str2字符串相等的首地址 没找到返回-1
//2. string& replace(int pos, int n, const string& str);
//替换从 pos 开始 n 个 字符为字符串 str
str1.replace(5,4,"hellowrold"); //从下标为5到5+4的字符替换为helloworld
cout<<str1<<endl; //haha:helloworld:xixi
//案例 将路径中的sex替换成***
string ur1 = "http://www.sex.666.sex.777.sex.com";
int pos = 0; //使用pos标记下标
while(1)
{
pos = ur1.find("sex",pos); //找到返回"sex"字符串的首下标 找不到"sex"字符串会返回-1
if(pos == -1) //返回-1后跳出循环
{
break;
}
ur1.replace(pos,3,"***"); //将返回的下标后的三个字符改为'*'
}
cout<<ur1<<endl;
}
字符串比较(compare)
int compare(const string &s) const | 与字符串 s 比较 |
int compare(const char *s) const; | 与字符串 s 比较 |
compare 函数在>时返回 1,<时返回 -1,==时返回 0。 比较区分大小写,比较时参考字典顺序,排越前面的越小。 大写的 A 比小写的 a 小。
字符串比较和案例 根据":"提取出所有字符 并打印 (he:haha:xixixi:lala:heihei)
void test_01()
{
string str1 = "hello";
string str2 = "hello"; //定义两个string变量
if(str1<str2) //1.使用'<' '>' '=='来判断大小
{
cout<<"小于"<<endl;
}else if(str1>str2){
cout<<"大于"<<endl;
}else{
cout<<"等于"<<endl;
}
if(str1.compare(str2)<0) //2.使用string类中的方法判断大小
{
cout<<"小于"<<endl;
}else if(str1.compare(str2)>0){
cout<<"大于"<<endl;
}else{
cout<<"等于"<<endl;
}
//案例:根据':'提取所有字串 并打印输出
string str3 = "he:haha:xixixi:lala:heihei";
string str; //定义一个空string
int pos = 0; //标记位置
while(1) //循环
{
int ret = str3.find(":",pos); //从pos位置查找":"的位置 并赋值给ret
if(ret == -1) //查找完毕后 返回-1
{
str += str3.substr(pos,str3.size()-pos);
break;
}
//将上轮循环查找到的":"后的字符串到本轮查找到的":"之前相加
str += str3.substr(pos,ret-pos);
pos = ret+1; //跳过本次查找到的":"
}
cout<<str<<endl; //打印 :hehahaxixixilalaheihei
}
插入和删除(insert erase)
string& insert(int pos, const char* s); | 插入字符串(char*位置也可替换string) |
string& insert(int pos, int n, char c); | 在指定位置插入 n 个字符 c |
string& erase(int pos, int n = npos); | 删除从 Pos 开始的 n 个字符 |
void test_01()
{
//1. string& insert(int pos, int n, char c);
//在指定位置插入 n 个字符 c
string str1 = "hello,world";
str1.insert(5,"hehe"); //从下标为5的位置插入"hehe"
cout<<str1<<endl; //hellohehe,world
//2. string& erase(int pos, int n = npos);
//删除从 Pos 开始的 n 个字符
str1.erase(5,4); //从下标为5的位置向后删除4个字符
cout<<str1<<endl; //hello,world
}
string和char *转换
void test_01()
{
//1. const char* 转换为string
string str1 = "hello";
cout<<str1<<endl; //hello
//2. string转const char*
string str2("hello world");
const char* p = str2.c_str();
cout<<p<<endl; //hello world
//3. const char*转非const
char* p2 = const_cast<char*>(p);
cout<<p2<<endl; //hello world
}
扩展
提示: 为了修改 string 字符串的内容,下标操作符[]和 at 都会返回字符的引用。但当字符串的内存被重新分配之后,可能发生错误.
void test_01()
{
string s = "abcdefg";
char& a = s[2];
char& b = s.at(3);
a = '1';
b = '2';
cout << s << endl;
cout << (int*)s.c_str() << endl;
s = "pppppppppppppppppppppppp";
//a = '1'; //ERROR
//b = '2';
cout << s << endl;
cout << (int*)s.c_str() << endl;
}