Files
Data-Structure/STL/STL-String/README.md
e2hang c5fcf58332 STL
2025-08-01 00:26:26 +08:00

299 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`std::string` 是 C++ 标准模板库STL中的一个非常重要的类用于处理文本字符串。它是 `std::basic_string<char>` 的 typedef定义在头文件 `<string>` 中。
下面我为你系统总结 `std::string` 的所有常用用法和函数,按类别分类,力求全面:
---
### 🔹 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` |
---
如你需要我可以给出一份“对比总结笔记表格Markdown/LaTeX/PDF”或演示更复杂转换例子。要吗