516 lines
22 KiB
Markdown
516 lines
22 KiB
Markdown
`std::string` 是 C++ 标准模板库(STL)中的一个非常重要的类,用于处理文本字符串。它是 `std::basic_string<char>` 的 typedef,定义在头文件 `<string>` 中。
|
||
|
||
下面我为你系统总结 `std::string` 的所有常用用法和函数,按类别分类,力求全面:
|
||
|
||
好的,我帮你整理一个 **C++ `std::string` 方法大全表格**,把常用方法、功能、参数和示例都列清楚,方便快速查阅。
|
||
|
||
| 方法 / 操作 | 功能说明 | 参数 | 返回值 / 备注 | 示例 |
|
||
| --------------------------------------------------------- | ---------- | ------------------------------------------------- | ---------------------------- | ------------------------------------------------------ |
|
||
| 构造 | 创建字符串 | `string s;`、`string s("abc");`、`string s(5,'x');` | - | `string s(3,'a'); // "aaa"` |
|
||
| `size()` / `length()` | 字符串长度 | 无 | `size_t` | `s.size();` |
|
||
| `empty()` | 是否为空 | 无 | `bool` | `s.empty();` |
|
||
| `operator[]` | 访问字符 | 索引 | `char&` | `s[0]='H';` |
|
||
| `at()` | 安全访问字符 | 索引 | `char&`,越界抛异常 | `s.at(1);` |
|
||
| `front()` / `back()` | 第一个/最后一个字符 | 无 | `char&` | `s.front();` |
|
||
| `push_back(c)` | 添加字符到末尾 | `char c` | void | `s.push_back('!');` |
|
||
| `pop_back()` | 删除末尾字符 | 无 | void | `s.pop_back();` |
|
||
| `append(str)` / `+=` | 拼接字符串 | `string` / `char*` | void | `s += "abc";` / `s.append("def");` |
|
||
| `insert(pos, str)` / `insert(it, c)` | 插入字符串或字符 | 位置 / 迭代器,字符串或字符 | void | `s.insert(2,"XY");` |
|
||
| `erase(pos, len)` / `erase(it)` | 删除部分或单字符 | 位置和长度 / 迭代器 | void | `s.erase(0,3);` |
|
||
| `replace(pos, len, str)` | 替换子串 | 位置,长度,字符串 | void | `s.replace(0,2,"Hi");` |
|
||
| `clear()` | 清空字符串 | 无 | void | `s.clear();` |
|
||
| `substr(pos, len)` | 子串 | 位置和长度 | `string` | `s.substr(1,3);` |
|
||
| `find(str)` / `rfind(str)` | 查找子串 | 字符串 | 索引/`npos` | `s.find("ab");` |
|
||
| `find_first_of(str)` / `find_last_of(str)` | 查找字符集合 | 字符串 | 索引/`npos` | `s.find_first_of("aeiou");` |
|
||
| `compare(str)` | 字符串比较 | 字符串 | <0 / 0 / >0 | `s1.compare(s2);` |
|
||
| `c_str()` | 转 C 风格字符串 | 无 | `const char*` | `cout << s.c_str();` |
|
||
| `stoi(s)` / `stol(s)` / `stoll(s)` | 字符串转整数 | 字符串 | int / long / long long | `int n = stoi("123");` |
|
||
| `stof(s)` / `stod(s)` / `stold(s)` | 字符串转浮点 | 字符串 | float / double / long double | `double d = stod("3.14");` |
|
||
| `to_string(val)` | 数值转字符串 | 数值类型 | string | `string s = to_string(42);` |
|
||
| `begin()` / `end()` | 迭代器 | 无 | iterator | `for(auto it=s.begin(); it!=s.end(); ++it)` |
|
||
| `rbegin()` / `rend()` | 反向迭代器 | 无 | reverse\_iterator | `reverse(s.rbegin(), s.rend());` |
|
||
| `swap(s2)` | 交换字符串 | string | void | `s1.swap(s2);` |
|
||
| `resize(n, c)` | 改变长度 | 新长度, 可选填充字符 | void | `s.resize(5,'x');` |
|
||
| `reserve(n)` | 预留容量 | 整数 | void | `s.reserve(100);` |
|
||
| `capacity()` | 当前容量 | 无 | size\_t | `s.capacity();` |
|
||
| `shrink_to_fit()` | 压缩容量 | 无 | void | `s.shrink_to_fit();` |
|
||
| `sort(begin,end)` / `reverse(begin,end)` | 排序/反转 | 迭代器区间 | void | `sort(s.begin(),s.end()); reverse(s.begin(),s.end());` |
|
||
| `isalpha(c)` / `isdigit(c)` / `toupper(c)` / `tolower(c)` | 字符操作 | 字符 | bool / char | `toupper('a');` |
|
||
|
||
---
|
||
|
||
💡 **额外提示**:
|
||
|
||
1. `string` 是动态数组,可以用迭代器操作像 `vector` 一样。
|
||
2. 可以用范围 `for` 遍历:
|
||
|
||
```cpp
|
||
for(char c : s) cout << c;
|
||
```
|
||
|
||
3. 没有 `push_front`,插入开头用 `insert(s.begin(), c)`
|
||
4. 与 C 风格字符串互转:`c_str()` 和 `string(s)`
|
||
|
||
---
|
||
|
||
如果你愿意,我可以帮你画一个**图解版“string 功能地图”**,把 **初始化、访问、修改、拼接、查找、转换、迭代、IO** 全部画成一张图,视觉化一看就懂。
|
||
|
||
你想要我画吗?
|
||
|
||
---
|
||
|
||
### 🔹 1. **构造函数**
|
||
|
||
```cpp
|
||
std::string s1; // 空字符串
|
||
std::string s2("hello"); // 从 C 字符串构造
|
||
std::string s3(s2); // 拷贝构造
|
||
std::string s4(s2, 1, 3); // 从 s2 的第1个字符起拷贝3个字符 -> "ell"
|
||
std::string s5(5, 'x'); // 重复字符 -> "xxxxx"
|
||
std::string s6 = {'a','b','c'}; // 用 initializer_list
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 2. **赋值和操作符**
|
||
|
||
```cpp
|
||
s1 = "world";
|
||
s2 = s1;
|
||
s3 = std::move(s1); // 移动赋值
|
||
s1 += "!"; // 拼接
|
||
std::string s = s2 + s3;
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 3. **基本成员函数**
|
||
|
||
```cpp
|
||
s.size(); // 返回长度
|
||
s.length(); // 同 size()
|
||
s.empty(); // 是否为空
|
||
s.clear(); // 清空
|
||
s.capacity(); // 当前容量
|
||
s.reserve(100); // 预留容量
|
||
s.shrink_to_fit(); // 收缩容量
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 4. **访问字符**
|
||
|
||
```cpp
|
||
s[i]; // 下标访问(不检查越界)
|
||
s.at(i); // 带越界检查
|
||
s.front(); // 第一个字符
|
||
s.back(); // 最后一个字符
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 5. **修改字符串**
|
||
|
||
```cpp
|
||
s.insert(pos, "abc"); // 插入字符串
|
||
s.insert(pos, 5, 'x'); // 插入5个x
|
||
s.erase(pos, len); // 删除从 pos 起 len 个字符
|
||
s.replace(pos, len, "newstr"); // 替换部分内容
|
||
s.push_back('c'); // 追加一个字符
|
||
s.pop_back(); // 移除最后一个字符
|
||
s.append("extra"); // 追加字符串
|
||
s.swap(s2); // 交换两个字符串
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 6. **查找字符串**
|
||
|
||
```cpp
|
||
s.find("abc"); // 查找子串,返回位置或 string::npos
|
||
s.find("abc", pos); // 从指定位置起查找
|
||
s.rfind("abc"); // 反向查找
|
||
s.find_first_of("abc"); // 查找任一字符
|
||
s.find_last_of("abc"); // 查找任一字符(从后往前)
|
||
s.find_first_not_of(" \n"); // 找第一个不是空格或换行的字符
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 7. **子串**
|
||
|
||
```cpp
|
||
s.substr(pos); // 从 pos 到末尾的子串
|
||
s.substr(pos, len); // 从 pos 起 len 个字符
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 8. **比较字符串**
|
||
|
||
```cpp
|
||
s1 == s2;
|
||
s1 != s2;
|
||
s1 < s2;
|
||
s1.compare(s2); // 返回 <0, =0, >0
|
||
s1.compare(pos, len, s2);
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 9. **C 风格字符串**
|
||
|
||
```cpp
|
||
s.c_str(); // 返回 const char* 指针
|
||
s.data(); // 类似 c_str(),但 C++17 起返回非 null 终止的指针
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 10. **迭代器**
|
||
|
||
```cpp
|
||
s.begin(); s.end(); // 正向迭代器
|
||
s.rbegin(); s.rend(); // 反向迭代器
|
||
const_iterator it = s.cbegin(); // 常量迭代器
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 11. **输入输出**
|
||
|
||
```cpp
|
||
std::cin >> s; // 读入单词
|
||
std::getline(std::cin, s); // 读入整行(包含空格)
|
||
std::cout << s; // 输出字符串
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 12. **其他函数**
|
||
|
||
```cpp
|
||
s.resize(10); // 改变字符串长度
|
||
s.resize(10, 'x'); // 用'x'填充
|
||
std::hash<std::string>{}(s); // 获取哈希值
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 13. **C++20 增强**
|
||
|
||
在 C++20 中,`std::string` 支持了 Ranges、`starts_with()`、`ends_with()` 等:
|
||
|
||
```cpp
|
||
s.starts_with("http"); // 是否以 http 开头
|
||
s.ends_with(".com"); // 是否以 .com 结尾
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 14. **和 C 字符串兼容**
|
||
|
||
```cpp
|
||
const char* cstr = s.c_str(); // 可用于 C 函数如 printf("%s", s.c_str())
|
||
std::string(some_c_str); // 从 C 字符串构造
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 15. **字符串与数字转换**
|
||
|
||
```cpp
|
||
int i = std::stoi("123");
|
||
double d = std::stod("3.14");
|
||
std::string s = std::to_string(42);
|
||
```
|
||
|
||
---
|
||
|
||
如需我帮你整理成一份笔记或 Markdown 文件,也可以告诉我!你也可以提你最常用的用法,我帮你列举示例。
|
||
|
||
|
||
|
||
|
||
`std::string` 和 `C-style string (cstring)` 是 C++ 中处理字符串的两种主要方式,它们的 **区别与联系** 如下。
|
||
|
||
---
|
||
|
||
## 🧠 一句话总结:
|
||
|
||
> **`std::string` 是 C++ 的高级封装,`cstring` 是 C 语言风格的低级字符数组。**
|
||
|
||
---
|
||
|
||
## 🔍 一、基本概念对比
|
||
|
||
| 特性 | `C-style string (cstring)` | `std::string` |
|
||
| ---- | ---------------------------------------- | -------------------------------------------- |
|
||
| 本质 | 字符数组(如 `char[]`)以 `\0` 结尾 | 类模板 `std::basic_string<char>` |
|
||
| 所属 | C 标准库 `<cstring>` | C++ 标准库 `<string>` |
|
||
| 内存管理 | 需手动管理(如 `new`、`strcpy`) | 自动管理(RAII) |
|
||
| 长度 | 用 `strlen()` 计算 | `s.length()` |
|
||
| 操作 | 用 `strcpy()`、`strcat()`、`strcmp()` 等函数操作 | 用成员函数 `.append()`、`.substr()`、`.compare()` 等 |
|
||
| 安全性 | 易越界、易内存泄露 | 更安全 |
|
||
| 可变性 | 必须预留空间 | 动态扩展 |
|
||
| 推荐 | 适合底层接口、嵌入式等 | 推荐用于现代 C++ 开发 |
|
||
|
||
---
|
||
|
||
## 📦 二、cstring 提供了哪些函数(头文件 `<cstring>`)
|
||
|
||
| 函数名 | 说明 |
|
||
| ------------------------------------------- | ---------------- |
|
||
| `strlen(const char*)` | 计算字符串长度(不包括`\0`) |
|
||
| `strcpy(char*, const char*)` | 拷贝字符串 |
|
||
| `strncpy(char*, const char*, size_t)` | 安全拷贝 |
|
||
| `strcat(char*, const char*)` | 字符串拼接 |
|
||
| `strcmp(const char*, const char*)` | 比较字符串 |
|
||
| `strncmp(const char*, const char*, size_t)` | 比较前 n 个字符 |
|
||
| `strchr(const char*, char)` | 查找字符首次出现 |
|
||
| `strrchr(const char*, char)` | 查找字符最后一次出现 |
|
||
| `strstr(const char*, const char*)` | 查找子串首次出现 |
|
||
| `memcpy(void*, const void*, size_t)` | 内存拷贝 |
|
||
| `memset(void*, int, size_t)` | 内存初始化 |
|
||
| `memcmp(const void*, const void*, size_t)` | 内存比较 |
|
||
|
||
> ⚠️ 注意:这些函数不会检查数组越界,必须手动保证空间足够!
|
||
|
||
---
|
||
|
||
## 🎁 三、std::string 提供了哪些成员函数(头文件 `<string>`)
|
||
|
||
详见我上一个回答,但可以再快速总结:
|
||
|
||
* 构造 / 赋值:`std::string s("abc");`
|
||
* 长度:`s.length()`, `s.empty()`
|
||
* 访问:`s[i]`, `s.at(i)`
|
||
* 修改:`s += "abc"`, `s.insert()`, `s.erase()`, `s.replace()`
|
||
* 查找:`s.find("abc")`, `s.substr()`
|
||
* 比较:`s1 == s2`, `s.compare()`
|
||
* 迭代器:`begin()`, `end()`
|
||
* 与 cstring 转换:`s.c_str()`
|
||
|
||
---
|
||
|
||
## 🔁 四、二者之间的联系与转换
|
||
|
||
### ✅ `std::string` 转 `cstring`
|
||
|
||
```cpp
|
||
std::string s = "hello";
|
||
const char* cstr = s.c_str(); // 注意:是 const char*!
|
||
```
|
||
|
||
> ⚠️ 不可以对 `cstr` 写入内容。`c_str()` 返回的内存由 `std::string` 管理。
|
||
|
||
### ✅ `cstring` 转 `std::string`
|
||
|
||
```cpp
|
||
const char* cstr = "world";
|
||
std::string s = cstr;
|
||
```
|
||
|
||
---
|
||
|
||
## 💥 五、示例比较
|
||
|
||
```cpp
|
||
#include <iostream>
|
||
#include <cstring>
|
||
#include <string>
|
||
|
||
int main() {
|
||
// C-style string
|
||
char a[20] = "Hello";
|
||
strcat(a, " World"); // 注意要有足够空间
|
||
std::cout << a << std::endl;
|
||
|
||
// std::string
|
||
std::string s = "Hello";
|
||
s += " World"; // 更安全简洁
|
||
std::cout << s << std::endl;
|
||
|
||
// 转换
|
||
const char* cstr = s.c_str(); // std::string → cstring
|
||
std::string s2 = cstr; // cstring → std::string
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ 六、什么时候用哪个?
|
||
|
||
| 场景 | 推荐用法 |
|
||
| ----------------------------- | ------------------------ |
|
||
| 日常开发 | `std::string`(更安全易用) |
|
||
| 与 C 接口交互(如 `printf`, `fopen`) | 使用 `std::string.c_str()` |
|
||
| 内存受限嵌入式环境 | `cstring` |
|
||
| 学习 C 语言基础 | `cstring` |
|
||
|
||
---
|
||
|
||
好的,我们来整理一个 **C++ `std::string` 的使用大全**,我会尽量覆盖几乎所有常用操作、方法和用法,包括初始化、访问、修改、查找、比较、输入输出、拼接、转换等,并附带示例。
|
||
|
||
---
|
||
|
||
# **C++ `std::string` 使用大全**
|
||
|
||
```cpp
|
||
#include <iostream>
|
||
#include <string>
|
||
#include <algorithm>
|
||
#include <cctype>
|
||
using namespace std;
|
||
|
||
int main() {
|
||
// ================================
|
||
// 1. 初始化
|
||
// ================================
|
||
string s1; // 空字符串
|
||
string s2("Hello"); // 用 C 风格字符串初始化
|
||
string s3(s2); // 拷贝构造
|
||
string s4(5, 'x'); // 生成 "xxxxx"
|
||
|
||
// ================================
|
||
// 2. 访问字符
|
||
// ================================
|
||
char c1 = s2[0]; // 'H'
|
||
char c2 = s2.at(1); // 'e',越界会抛异常
|
||
char &ref = s2[0]; // 可修改
|
||
s2[0] = 'h'; // 修改为 "hello"
|
||
|
||
// ================================
|
||
// 3. 拼接
|
||
// ================================
|
||
string s5 = s2 + " world"; // "hello world"
|
||
s2 += "!"; // "hello!"
|
||
s2.append(" C++"); // "hello! C++"
|
||
|
||
// 插入
|
||
s2.insert(6, "my "); // "hello!my C++"
|
||
|
||
// ================================
|
||
// 4. 删除
|
||
// ================================
|
||
s2.erase(6, 3); // 从位置6删除3个字符
|
||
s2.pop_back(); // 删除最后一个字符
|
||
|
||
// ================================
|
||
// 5. 长度与大小
|
||
// ================================
|
||
size_t len = s2.length(); // 字符串长度
|
||
size_t size = s2.size(); // 同 length()
|
||
bool empty = s2.empty(); // 是否为空
|
||
|
||
// ================================
|
||
// 6. 查找
|
||
// ================================
|
||
size_t pos1 = s2.find("llo"); // 返回子串位置,找不到返回 npos
|
||
size_t pos2 = s2.rfind("o"); // 从右往左查找
|
||
size_t pos3 = s2.find_first_of("aeiou"); // 找到第一个元音字母
|
||
size_t pos4 = s2.find_last_of("aeiou"); // 找到最后一个元音字母
|
||
|
||
// ================================
|
||
// 7. 比较
|
||
// ================================
|
||
string a = "abc", b = "abd";
|
||
int cmp = a.compare(b); // <0 a<b, 0 a=b, >0 a>b
|
||
|
||
// ================================
|
||
// 8. 子串
|
||
// ================================
|
||
string sub = s2.substr(0, 5); // 从位置0开始,长度5
|
||
|
||
// ================================
|
||
// 9. 转换
|
||
// ================================
|
||
string strNum = "123";
|
||
int num = stoi(strNum); // string -> int
|
||
long long ll = stoll(strNum); // string -> long long
|
||
float f = stof("3.14"); // string -> float
|
||
double d = stod("3.14159"); // string -> double
|
||
string str1 = to_string(456); // int -> string
|
||
|
||
// ================================
|
||
// 10. 排序/反转
|
||
// ================================
|
||
reverse(s2.begin(), s2.end()); // 反转字符串
|
||
sort(s2.begin(), s2.end()); // 字典序排序
|
||
|
||
// ================================
|
||
// 11. 遍历
|
||
// ================================
|
||
for(char ch : s2) cout << ch << " "; // 范围 for
|
||
for(size_t i = 0; i < s2.size(); i++) cout << s2[i];
|
||
|
||
// ================================
|
||
// 12. 插入/删除字符操作
|
||
// ================================
|
||
s2.push_back('!'); // 在末尾加字符
|
||
s2.insert(s2.begin(), 'H'); // 在开头插入字符
|
||
s2.erase(s2.begin()); // 删除开头字符
|
||
|
||
// ================================
|
||
// 13. 比较大小/字典序
|
||
// ================================
|
||
if("abc" < "abd") cout << "abc < abd";
|
||
|
||
// ================================
|
||
// 14. 清空
|
||
// ================================
|
||
s2.clear(); // 清空字符串
|
||
|
||
// ================================
|
||
// 15. 转换为 C 风格字符串
|
||
// ================================
|
||
const char* cstr = s2.c_str();
|
||
|
||
// ================================
|
||
// 16. 替换
|
||
// ================================
|
||
s2.replace(0, 3, "HELLO"); // 将前3个字符替换成 HELLO
|
||
|
||
// ================================
|
||
// 17. 字符判断/转换
|
||
// ================================
|
||
for(char &ch : s2) {
|
||
if(isalpha(ch)) ch = toupper(ch); // 转大写
|
||
}
|
||
|
||
// ================================
|
||
// 18. 流操作
|
||
// ================================
|
||
string input;
|
||
cin >> input; // 读取单个单词
|
||
getline(cin, input); // 读取整行
|
||
cout << input << endl;
|
||
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ 总结
|
||
|
||
`std::string` 能做的事情非常多,大体可分为:
|
||
|
||
1. **初始化/赋值/复制**
|
||
2. **访问/修改字符**
|
||
3. **拼接、插入、删除、替换**
|
||
4. **长度、空性检查**
|
||
5. **查找、子串、比较**
|
||
6. **遍历**
|
||
7. **转换类型**
|
||
8. **排序、反转、大小写转换**
|
||
9. **C 风格字符串接口**
|
||
10. **输入输出**
|
||
|
||
---
|
||
|
||
如果你愿意,我可以帮你画一张\*\*`string` 方法总结表格\*\*,把**所有方法、功能、返回值和示例**一页就能看到,像官方手册一样直观。
|
||
|
||
你想让我画吗?
|
||
|