<!--markdown--># C++ string 常用函数总结
一、基础信息与字符访问
size()/length():获取字符串长度,两者完全等价,建议统一用size()
例:string s = "abc"; cout << s.size(); // 输出3
s[pos]:按下标访问字符,下标从0开始,越界行为未定义
例:string s = "abc"; cout << s[1]; // 输出b
front():获取第一个字符
例:string s = "abc"; cout << s.front(); // 输出a
back():获取最后一个字符
例:string s = "abc"; cout << s.back(); // 输出c
c++遍历代码示例:
for(int i = 0; i < l ; i++)
{
str[i];
}
for(auto c : str) // auto:自动类型 冒号做容器遍历
{
c;
}
二、查找
s.find(str):从字符串开头查找str第一次出现的下标
例:string s = "abcabc"; cout << s.find("bc"); // 输出1
s.find(str, pos):从下标pos开始查找str第一次出现的下标
例:string s = "abcabc"; cout << s.find("bc", 2); // 输出4
s.rfind(str):从字符串末尾向前查找str最后一次出现的下标
例:string s = "abcabc"; cout << s.rfind("bc"); // 输出4
- 所有查找函数找不到目标时,返回
string::npos
例:if (s.find("xyz") == string::npos) { cout << "没找到"; }
c++// 找str里有几个target
int p = 0; // 最近一次找到的位置
while(1)
{
p = str.find(target, p); //用新找到的位置替换老位置
if(p == string::npos) break;
p += target.size(); // 跳过刚找到的这个,接着往后找
cnt++;
}
三、子串、运算符支持 ⭐⭐⭐⭐⭐
s.substr(pos, len):截取从下标pos开始的len个字符,返回新字符串;省略len则截取到末尾
例1:string s = "abcd"; string t = s.substr(1, 2); // t为"bc"
例2:string s = "abcd"; string t = s.substr(1); // t为"bcd"
- 支持
==!=<><=>=运算符,按字典序比较
例:cout << ("abc" < "abd"); // 输出1(true)
- 支持
++=,表示字符串之间的连接,注意string类型也可以加字符。
例1:string s1 = "ab"; string s2 = "cd"; string s = s1 + s2; // s为"abcd"
例2:string s = "ab"; ; s += 'c'; // s为"abc"
四、字符串/数字转换相关
数字转字符串
to_string(val):将数字val转换为string,支持int/long/float/double等所有常见数值类型
例:string s = to_string(123); // s为"123"
例:string s = to_string(3.14); // s为"3.140000"
字符串转数字
stoi(s):将字符串s转换为int
例:int x = stoi("123"); // x为123
stoll(s):将字符串s转换为long long
例:long long x = stoll("1234567890123");
stof(s):将字符串s转换为float
例:float x = stof("3.14");
stod(s):将字符串s转换为double
例:double x = stod("3.1415926");
五、排序与翻转
- 升序排序:
sort(s.begin(), s.end())
例:string s = "bac"; sort(s.begin(), s.end()); // s变为"abc"
- 降序排序:
sort(s.begin(), s.end(), greater<char>())
例:string s = "bac"; sort(s.begin(), s.end(), greater<char>()); // s变为"cba"
- 翻转:reverse(s.begin(), s.end());
例:string s = "abc"; reverse(s.begin(), s.end()); // s变为"cba"
六、ASCII表补充
- 记住三个ASCII表值:
'0' = 48, 'A' = 65, 'a' = 97 - 记住字符类型数字转对应整数:减去48或减去'0'
- 记住大小写字母转换,差值32
- 补充两个转换函数:
toupper(), tolower(),传入字符,自带判断,返回对应ASCII值。
例:cout << (char)tolower('A'); // 输出a
例:cout << tolower('A'); // 输出97 非a
例:cout << tolower('0'); // 输出48 不变
- 补充四个判断函数:
- isalpha(c) 是否为字母(大小写都行)
- islower(c) 是否为小写字母
- isupper(c) 是否为大写字母
- isdigit(c) 是否为数字 0~9
七、增删操作(可以利用substr模拟实现)
插入
s.insert(pos, str):在下标pos处插入字符串str
例:string s = "ac"; s.insert(1, "b"); // s变为"abc"
s.insert(pos, len, c):在下标pos处插入len个字符c
例:string s = "a"; s.insert(1, 2, 'b'); // s变为"abb"
删除
s.erase(pos, len):从下标pos开始删除len个字符
例:string s = "abcd"; s.erase(1, 2); // s变为"ad"
s.erase(it):删除迭代器it指向的单个字符
例:string s = "abc"; s.erase(s.begin()+1); // s变为"ac"
s.pop_back():删除最后一个字符
例:string s = "abc"; s.pop_back(); // s变为"ab"
注:以上函数都是原地修改
注意点
1. 所有下标均从0开始
2. 查找失败统一返回string::npos,必须用==判断
3. substr不修改原字符串,必须用变量接收返回值
4. 位置查询及取长度的返回值,均为size_t,无符号整型
5. 输入字符串时,如果前有cin,则使用getline前必须加一句getchar();
所有下标位置操作都是高频错误点,强烈建议写个字符串自己数一数,经常有+-或-1的细节修正。
___
字符串概念考察
一、两种字符串:string 与 char 数组
1. string(C++ 字符串,最常用)
- 必须包含头文件:
#include <string> - 定义:
string s = "GESP"; - 下标从 0 开始,有效下标:
0 ~ s.length()-1 - 末尾自动存
\0,但不算长度
2. char 字符数组(C 风格字符串)
char str[] = "Hello";- 实际存储:
H e l l o \0→ 长度 5,占空间 6 char str[] = {'H','e','l','l','o'};- 没有 \0,不是合法字符串,输出会乱码
- 必须以
\0结尾才算字符串 - 长度用
strlen(str),占空间用sizeof(str)
二、字符串高频操作
1. 大小写转换
小写 → 大写:s[i] -= 32 或 s[i] += 'A'-'a'
大写 → 小写:s[i] += 32 或 s[i] += 'a'-'A'
2. 字符数字转整数
int num = s[i] - '0';
3. 判断相等
- string:直接用
==(比较内容) - char 数组:必须用
strcmp(a,b)
三、最易混淆概念
1. 长度 vs 占空间
char s[]="abc";
strlen(s)=3,sizeof(s)=4(多一个 \0)
2. 下标越界
string s="chen"; 长度 4,下标到 3 为止,s[4] 是 \0,s[5] 乱码
3. cin 读取规则
遇到空格、回车、Tab 停止,想读整行用 getline
4. 转义字符
字符串里输出双引号/单引号:\" 或 \'
5. substr 越界
长度不够时,取到末尾为止,不抛异常
6. 中文占字节
取决于编码(GBK编码 一个汉字占2字节,UTF-8编码 一个汉字占3字节)
四、判断题必考点
1. string 的 == 比较的是内容,不是地址 → 对
2. substr(1,3) 是从下标1开始取3个字符 → 对
3. 字符数组赋值必须用 strcpy,不能直接 = → 对
4. find 找不到返回 npos,不是 -1 → 对
5. 字符串越界访问是未定义行为,不一定崩溃 → 对