C++ string 常用函数最全总结(2025最新版)
建议收藏 + 打印贴桌边,面试手写 + 日常开发 99% 用得到的就是这些!
| 功能分类 | 函数名 | 用法示例 | 说明 / 返回值 | 常见坑 / 注意事项 |
|---|---|---|---|---|
| 构造与赋值 | string s; | string s = "hello"; | 默认构造、空串 | |
string s(str) | string s2(s1); | 拷贝构造 | ||
string s(n, ch) | string s(5, '*'); → “*“ | n 个字符 ch | ||
string s(str, pos) | string s("hello", 2); → “llo” | 从 pos 开始到结尾 | pos 可越界但不能 > size() | |
s.assign(str) | s.assign("world"); | 赋值(清空后重新填) | ||
| 大小与容量 | s.size() / s.length() | int len = s.size(); | 返回字符个数(相同) | size_t 类型,无符号 |
s.empty() | if(s.empty()) | 是否为空 | ||
s.capacity() | cout << s.capacity(); | 当前分配的内存大小(不一定等于 size) | 很多实现是 15→31→63… 增长 | |
s.reserve(n) | s.reserve(100); | 预分配空间,避免频繁扩容 | 只增不减 | |
s.shrink_to_fit() (C++11) | s.shrink_to_fit(); | 请求释放多余容量 | 非强制,依赖实现 | |
| 增删改查 | s += str | s += "world"; | 拼接 | |
s.append(str) | s.append("123"); | 同上,更灵活 | ||
s.push_back(ch) | s.push_back('A'); | 追加单个字符 | ||
s.insert(pos, str) | s.insert(0, "pre"); | 在 pos 前插入 | pos 可 = size() | |
s.erase(pos, len) | s.erase(5, 3); | 从 pos 开始删 len 个字符 | len 可超,删到末尾 | |
s.clear() | s.clear(); | 清空 | size=0,capacity不变 | |
s.replace(pos, len, str) | s.replace(0, 5, "Hi"); | 替换子串 | 最常用 | |
| 访问 | s[i] | char c = s[0]; | 可读可写(不越界检查) | 越界 undefined behavior |
s.at(i) | char c = s.at(0); | 同上,但越界抛 out_of_range 异常 | 更安全 | |
s.front() (C++11) | char& c = s.front(); | 首字符引用 | ||
s.back() (C++11) | char& c = s.back(); | 末字符引用 | ||
s.data() / s.c_str() | const char* p = s.c_str(); | 返回 C 风格字符串(结尾有’\0’) | data() 在 C++17 前可能无’\0′ | |
| 查找 | s.find(str, pos=0) | size_t p = s.find("world"); | 从 pos 开始找,返回首次出现位置;没找到返回 npos | 最常用 |
s.rfind(str, pos=npos) | size_t p = s.rfind('.'); | 反向查找(最后一次出现) | ||
s.find_first_of(str, pos) | s.find_first_of("aeiou"); | 找任意一个字符首次出现 | ||
s.find_last_of() | 找最后一次 | 同上 | ||
s.find_first_not_of() | 找第一个不在集合中的字符 | |||
| 子串 | s.substr(pos=0, len=npos) | string sub = s.substr(7, 5); | 提取子串 | pos 可超(抛异常),len 可超(到末尾) |
| 比较 | s.compare(s2) | if(s.compare(t) == 0) | 字典序比较,返回 <0 / =0 / >0 | |
operator== / != / < > | if(s == "hello") | 同上,更直观 | ||
| 转换 | stoi / stol / stoll (C++11) | int n = stoi("12345"); | string → int/long/long long | 抛 invalid_argument / out_of_range |
stof / stod / stold | double d = stod("3.14"); | string → float/double/long double | ||
to_string(val) (C++11) | string s = to_string(3.14); | 数字 → string | 最方便 | |
| C++17 新神器 | string_view sv(s) | void f(string_view sv); | 非拥有式字符串视图,不拷贝,超快 | 不能修改,生命周期要注意 |
s.starts_with(str) (C++20) | if(s.starts_with("http")) | 判断前缀 | 超实用 | |
s.ends_with(str) (C++20) | if(s.ends_with(".jpg")) | 判断后缀 |
经典面试/竞赛高频操作(直接背)
// 1. 反转字符串
reverse(s.begin(), s.end());
// 2. 删除所有空格
s.erase(remove(s.begin(), s.end(), ' '), s.end());
// 3. 字符串转整数(手写 atoi)
int my_atoi(string s) {
int res = 0, sign = 1, i = 0;
while(i < s.size() && s[i]==' ') i++;
if(i < s.size() && (s[i]=='+' || s[i]=='-')) sign = (s[i++]=='-') ? -1 : 1;
while(i < s.size() && isdigit(s[i])) {
if(res > INT_MAX/10 || (res == INT_MAX/10 && s[i]-'0' > 7))
return sign == 1 ? INT_MAX : INT_MIN;
res = res * 10 + (s[i++]-'0');
}
return res * sign;
}
// 4. 判断回文串(忽略大小写和非字母)
bool isPalindrome(string s) {
int l = 0, r = s.size()-1;
while(l < r) {
while(l < r && !isalnum(s[l])) l++;
while(l < r && !isalnum(s[r])) r--;
if(tolower(s[l++]) != tolower(s[r--])) return false;
}
return true;
}
性能对比(LeetCode 实测)
| 操作 | string(拷贝) | string_view(C++17) | const string& |
|---|---|---|---|
| 传参开销 | 高(深拷贝) | 几乎为 0 | 几乎为 0 |
| 修改安全性 | 可修改 | 不可修改 | 不可修改 |
| 推荐场景 | 需要修改 | 大量只读传参 | 通用最优解 |
结论:能用 const string& 或 string_view 就别用值传递!
这张表 + 上面代码,直接打印贴显示器旁边,
保你写 C++ string 再也不卡壳,面试官看了都说好!
想要我出 PDF 版 + 思维导图 + 100道 string 经典题解,随时说一声!