以下是 C++ 中 std::string 常用成员函数 的系统整理和使用说明(基于 C++11/14/17/20/23 标准)。我会按功能分类整理,并附上典型用法和注意事项。
1. 构造与初始化
std::string s1; // 空字符串
std::string s2(10, 'a'); // "aaaaaaaaaa"
std::string s3("hello"); // 从 C 字符串构造
std::string s4("hello world", 5); // 前5个字符 → "hello"
std::string s5(s3.begin(), s3.end()); // 从迭代器范围构造
std::string s6 = "literal"; // 推荐写法(最常用)
std::string s7{s3}; // 拷贝构造(C++11 uniform init)
2. 基本信息查询
s.empty() // 是否为空
s.size() // 当前字符数(size_t)
s.length() // 与 size() 等价(历史遗留)
s.capacity() // 当前分配的容量
s.max_size() // 理论上能存储的最大字符数(极大值)
3. 访问字符
s[0] // 下标访问(不检查越界)
s.at(0) // 安全访问(越界抛 std::out_of_range)
s.front() // 第一个字符(C++11)
s.back() // 最后一个字符(C++11)
// 只读访问(返回 const char*)
s.c_str() // 以 \0 结尾的 C 风格字符串
s.data() // C++17 前等同 c_str(),C++17 后可能不带 \0
4. 修改内容(最常用操作)
| 函数 | 功能描述 | 示例 |
|---|---|---|
s += "text" | 追加字符串 | s += " world"; |
s += 'c' | 追加单个字符 | s += '!'; |
s.append("text") | 追加(功能同 +=) | s.append("!!!"); |
s.push_back('c') | 追加单个字符 | s.push_back('?'); |
s.pop_back() | 删除最后一个字符 | s.pop_back(); |
s.insert(pos, str) | 在 pos 位置插入字符串 | s.insert(5, "beautiful "); |
s.erase(pos, len) | 从 pos 开始删除 len 个字符 | s.erase(0, 6); // 删除前6个字符 |
s.replace(pos, len, str) | 用 str 替换 [pos, pos+len) 区间 | s.replace(7, 3, "C++"); |
s.clear() | 清空字符串 | s.clear(); |
s.resize(n) | 调整大小(n < size 截断,n > size 补 ‘\0’) | s.resize(10); |
s.reserve(n) | 预分配容量(避免频繁重新分配) | s.reserve(1000); |
5. 查找与比较
| 函数 | 功能 | 返回值 | 示例 |
|---|---|---|---|
s.find(str) | 查找子串第一次出现位置 | size_t(找到返回位置,未找到返回 npos) | s.find("world") |
s.rfind(str) | 从后向前查找 | 同上 | s.rfind("l") |
s.find_first_of(chars) | 查找任一字符第一次出现 | 同上 | s.find_first_of("aeiou") |
s.find_last_of(chars) | 查找任一字符最后一次出现 | 同上 | s.find_last_of("aeiou") |
s.find_first_not_of(chars) | 查找第一个不在 chars 中的字符 | 同上 | s.find_first_not_of(" \t\n") |
s.compare(other) | 字典序比较 | <0 / 0 / >0 | s.compare("hello") |
s.starts_with(prefix) | 是否以 prefix 开头(C++20) | bool | s.starts_with("http") |
s.ends_with(suffix) | 是否以 suffix 结尾(C++20) | bool | s.ends_with(".cpp") |
s.contains(sub) | 是否包含子串(C++23) | bool | s.contains("error") |
6. 子串与分割
// 提取子串
std::string sub = s.substr(pos, len); // 从 pos 开始取 len 个字符
std::string sub2 = s.substr(pos); // 从 pos 到末尾
// 按分隔符分割(C++17 以前没有内置,需要自己写)
std::vector<std::string> split(const std::string& s, char delim) {
std::vector<std::string> result;
std::stringstream ss(s);
std::string token;
while (std::getline(ss, token, delim)) {
result.push_back(token);
}
return result;
}
7. 常用操作示例合集
#include <iostream>
#include <string>
int main() {
std::string s = "Hello, C++ World!";
// 修改
s += " 2023";
s.insert(7, "Beautiful ");
s.replace(18, 4, "C++");
s.erase(0, 6);
std::cout << s << "\n"; // Beautiful C++ World! 2023
// 查找
size_t pos = s.find("C++");
if (pos != std::string::npos) {
std::cout << "Found 'C++' at position: " << pos << "\n";
}
// 比较
if (s.starts_with("Beautiful")) { // C++20
std::cout << "Starts with 'Beautiful'\n";
}
// 清空
s.clear();
std::cout << "After clear, size = " << s.size() << "\n";
return 0;
}
8. 常用技巧与注意事项
- 性能优化:
- 预先
reserve()容量,避免多次重新分配 - 大量拼接时优先使用
std::string::reserve()++= - 避免在循环中频繁构造临时字符串
- C++20/23 新增便利函数:
starts_with,ends_with,containsstd::string::erase重载(可直接删除子串)
- 常见陷阱:
s.c_str()返回的指针在字符串被修改后会失效s += c比s.push_back(c)略慢(但差距很小)substr(pos, len)中的 len 超出剩余长度不会抛异常
- 替代方案:
- 需要频繁修改中间部分 → 考虑
std::deque<char>或std::vector<char> - 需要极致性能 → 可使用
std::string_view(C++17)
如果你有具体的字符串处理需求(比如分割、格式化、正则替换等),可以告诉我,我可以给出更针对性的代码示例!