C++STL字符串string知识汇总,恶补!
基础不牢,地动山摇。
今天小米的笔试编程题,输入格式是一整个字符串,需要从字符串中分割出数据,同时还需要将字符串转换为int数值。
本来用C++写,写到一般想起来了C++中没有split()函数,想到在java中有这个函数,于是又换到了Java语言,但是Java的输入、输出又不方便,唉~~
这波,让我狠狠地补一下string的知识
今天来将C++ STL中,与字符串相关的东西总结一下。
string
在C++中,用string类变量来表示一个字符串,相比于C中的char[]
,更简单。
创建string字符串对象
创建一个string对象
string s; // 1. 一个空的字符串对象 string s1 = "lmk"; // 2. 创建指定内容的字符串 char st[] = {'1','a','b'}; string s2(st);// 3. 根据char[] 创建字符串 string s3(10, 'c'); // 4. 生成包含n个指定字符的字符串
常规用法
string字符串本质还是一个char[]
,所以我们可以利用[]
来访问指定位置的字符
string str = "abc"; cout << str[0] << endl; cout << str[2] << endl;
string重载了+
和+=
运算法,这两个运算符对于string对象,就是字符串拼接操作
string str = "abc"; cout << str + "1234" << endl; str += "xyz"; cout << str << endl; str += 'Y'; cout << str << endl;
string中常用的成员方法
迭代器:
begin()
用来标识字符串的起始位置,即第一个字符的位置end()
,用来表示字符串的结束位置,即最后一个字符的下一个位置
基本成员方法
首先是基本的成员方法
- 获取字符串长度
size()
或length()
- 判断字符串是否为空
empty()
- 清空字符串
clear()
string str = "lmkdsb"; cout << str.size() << " || " << str.length() << endl; str.clear(); cout << str.size() << " || " << str.length() << endl; cout << str.empty() << endl;
添加
字符串长度增加相关的方法
- 尾插单个字符
push_back(char ch)
- 追加字符串,
append(string str)
,此方法的参数是一个字符串,追加字符串后面 - 插入字符或字符串`insert(int pos, string)
string str = "lmkdsb"; str.push_back('x'); // 追加单个字符 cout << str << endl; str.append("123"); // 追加字符串 cout << str << endl; str.insert(1, "xyz"); // 在指定索引处插入字符串 cout << str << endl; str.insert(str.end(), 'Y'); // 如果要使用insert()在指定索引处插入一个字符,必须要使用迭代器来指明位置 cout << str << endl;
删除
删除字符串相关的方法
- 删除最后的那个字符,尾删
pop_back()
- 删除指定位置的一个或一些字符
earse()
string str = "lmkdsbxxxw"; str.pop_back(); // 删除末尾的单个字符 cout << str << endl; str.erase(6);// 从pos索引开始删除,一直到最后 cout << str << endl; str.erase(2, 3); // 从索引为2的位置开始,删除3个元素 cout << str << endl; str.erase(str.begin() + 1, str.end() - 1); // 配合迭代器,删除[start, end)之间的元素 cout << str << endl;
查找
字符串查找:
- find()从左侧开始查找,返回起始位置的坐标
- rfind()从右侧开始查找,返回起始位置的坐标
这两个方法如果找不到,那么就会返回string::npos
,(no position),此成员变量用来表示没有找到目标字符串。
此成员是一个long long unsigned int
类型的变量(64位无符号整型),npos
转换为int是会溢出,最终转换为int是-1
string str = "lmkdsbm"; cout << str.find('m') << endl; // 查找单个字符 cout << str.find("mk") << endl; // 查找子字符串 cout << str.find('m',1) << endl; //从指定位置开始查找,从[pos, ]开始查找 // 从右边开始查找 cout << str.rfind('m') << endl; cout << str.rfind("mk") << endl; cout << str.rfind('m', 3) << endl; // 从指定位置开始查找 // 找不到会返回npos cout << str.find('x') << endl; // 结果是 18446744073709551615 int pos = str.find('x'); // 转换为int会溢出,最终结果是-1 cout << pos << endl;
此外,还有两个查找相关的方法,与find()、rfind()相似:
find_first_of
查找第一个出现的位置find_last_of
查找最后出现的位置
string str = "lmkdsbmx"; // 查找第一个出现的位置 cout << str.find_first_of('m') << endl; cout << str.find_first_of('m', 1) << endl; // 从指定位置开始查找 // 查找第一个不包含指定子串的位置 cout << str.find_first_not_of('m', 1) << endl; cout << str.find_last_of('m') << endl; // 寻找最后出现的位置 cout << str.find_last_not_of('m') << endl; // 寻找最后不出现目标字符串的位置
两个字符串交换内容,swap(string str)
string str = "abc"; string tmp ="1231"; str.swap(tmp); // swap()的参数必须是一个变量,不能是一个字符串常量,str.swap("123")这种写法是不可以的 cout << str << endl; cout << tmp << endl;
替换
replace(pos, n, string&)
从pos位置开始长度为n的这段区间替换为str。
replace(pos,n, m, char ch)
从pos位置开始长度为n的这段区间替换为m个ch
string str = "abcdef"; str.replace(2,2, "lmk"); cout << str << endl; string s = "xyzw"; s.replace(1,2,8,'k'); cout << s << endl;
字符串分割
substr(pos, n)从字符串中分割出子串,从pos位置开始,截取n个字符并返回
string str = "abc123"; cout << str.substr(2) << endl; // 从指定位置开始截取,一直到结尾 cout << str.substr(3,3) << endl; // 从指定位置pos开始截取n个字符
在C++中,并没有split()函数,其他语言中都有这个函数,这个函数的作用就是按照指定的字符串作为分割,返回分割后的结果。
例如,string str = "13,2,3"
,按照split()所说的,我们按照逗号,
进行分割,分割后的结果应该是一个数组,["13,"2","3]"
我们可以手动实现这个函数,实现的思路有很多种,我们这里以find()
和substr()
来实现
vector<string> split(string str, string separator){ vector<string> res; int pos = str.find(separator); while(pos != -1){ string part = str.substr(0, pos); res.push_back(part); str = str.substr(pos + 1); pos = str.find(separator); } if(!str.empty()){ res.push_back(str); } return res; }
关于更多split()方法的实现方式可以看Site Unreachable
其他操作
字符转换大小写
- tolower(char ch) 将一个字符转换为小写并返回
- toupper(char ch)将一个字符转换为大写并返回
char ch = 'a'; ch = toupper(ch); // 转换为大写 cout << ch << endl; ch = tolower('Q'); // 转换为小写 cout << ch << endl; ch = tolower('2'); // 如果不能转换,则原样返回 cout << ch << endl;
字符判断
判断一个字符是不是字母、是不是大/小写字母、是不是数字
cout << isupper('A') << endl; // 是否是大写字母 cout << isupper('a') << endl; cout << islower('A') << endl; // 是否为小写字母 cout << isdigit('1') << endl; // 是否是数字 cout << isdigit('x') << endl; cout << isalpha(',') << endl; // 是否为字母 cout << isalpha('X') << endl;
string字符串与其他基本数据类型的转换
对于string字符串风格的对象来说,将一个string转换为int,可以使用stoi(string& str)
函数,除此之外还有:
- stoi(), string对象转换为int
- stof(),string对象转换为float
- stod(),string对象转换为double
- stoll(),string对象转换为long long
string str = "123"; int num = stoi(str); // string 转换为int cout << num + 5 << endl; str = "123.456"; // 转换为float cout << stof(str) + 0.1 << endl; cout << stod(str) << endl; // 转换为double str = "123212354312523292"; long long x = stoll(str); cout << x << endl; // 转换为long long 类型
你可能还听说过C 函数库中有一个atoi()
将字符串转换为int,这个atoi(char* s)
函数的参数是一个C风格的字符串,即一个char的数组,不能传递string对象作为参数。
其他数据类型转换为string
可以调用to_string()函数,该方法是C++11中新增的,该函数可以将其他所有的基本数据类型转换为字符串
string s = to_string(123); s.pop_back(); cout << s << endl; string st = to_string(123.456); cout << st << endl;
字符串反转
可以直接调用STL中的reverse()
函数,
该函数需要两个参数:
- 第一个参数,容器的起始位置
- 第二个参数,容器的结束位置
string str = "abcdef"; reverse(str.begin(), str.end()); cout << str << endl;
sort()与string
我们知道STL中,sort()是对容器内元素进行排序的,同样也支持对string对象中字符的排序,因为我们可以把string对象看做盛放字符的容器。
众所周知,sort()函数至少需要两个参数:
- 第一个是容器的开始位置,
- 第二个是结束位置,
- 第三个参数是可选的,自定义排序规则。
string str = "cbadfe"; sort(str.begin(), str.end()); cout << str << endl; // 结果是 abcdef
对于sort()函数来说,如果不传入自定义的比较规则,则会按照从小到大的顺序排序,对于字符来说,会按照字典序排序。
transform()
transform()
函数的作用就是将一个容器中的所有元素做出转换。
比如,我的字符串是"abc"
可以利用transform()将字符串中的元素全部转换为大写"ABC"
transform()有多个重载形式,对于string来说,就这种形式比比较常用
transform(begin, end, res, operation)
- begin容器的起始位置
- end容器的结束位置
- res,用来接受转换完成后的结果,从哪个变量的哪个位置开始接收转换后的结果
- operation,具体的转换逻辑,我们可以使用STL内置的函数,也可以自定义
以转换大写字母为例,
string str = "abcdefg"; transform(str.begin(), str.end(), str.begin(), ::toupper);// ::这两个冒号不可以省略 cout << str;
当然自定义逻辑也是很简单的
// 是大写就转换为小写,是小写就转换为大写 char myChange(char ch){ if(isupper(ch)){ return tolower(ch); }else{ return toupper(ch); } } int main() { string str = "aBcDeFg"; transform(str.begin(), str.end(), str.begin(), myChange);// ::这两个冒号不可以省略 cout << str; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构