1. 引言
什么是字符串?
字符串是由一系列字符组成的序列,用于表示文本信息。它在编程中被广泛应用于用户交互、文件处理、数据解析等场景。
C 风格字符串 vs std::string
在 C++ 中,有两种主要的字符串类型:
- C 风格字符串(C-strings):基于字符数组,以空字符 (
'\0') 结尾。 - C++
std::string类:更高级、功能更丰富的字符串类,封装了字符串操作的复杂性。
C 风格字符串示例:
1 | char cstr[] = "Hello, World!"; |
std::string 示例:
1 |
|
2. std::string 基础
定义与初始化
std::string 是 C++ 标准库中的一个类,位于 <string> 头文件中。它封装了字符序列,并提供了丰富的成员函数用于操作字符串。
初始化有很多中方式,如下图

包含头文件:
1 |
初始化示例:
1 |
|
输出:
1 | str1: |
字符串输入与输出
输出字符串:
1 |
|
从用户输入字符串:
1 |
|
读取包含空格的整行字符串:
1 |
|
3. 字符串操作
常用的字符串操作如下:

3.1 拼接与连接
使用 + 运算符:
1 |
|
使用 append() 函数:
1 |
|
使用 += 运算符:
1 |
|
3.2 比较字符串
关于字符串的比较,其实是逐个位置按照字符比较,计算机中字符存储的方式是ASCII码表,每个字符对应一个ASCII码值,比较字符就是比较ASCII码值的大小
一些控制字符也是通过ASCII码存储的
使用 ==, !=, <, >, <=, >= 运算符:
1 |
|
输出:
1 | a 和 b 不相等 |
3.3 查找与替换
使用 find() 查找子字符串:
1 |
|
替换子字符串:
1 |
|
3.4 子字符串与切片
使用 substr() 获取子字符串:
1 |
|
注意: 如果省略第二个参数,substr() 会返回从起始位置到字符串末尾的所有字符。
1 | std::string sub = str.substr(7); // 从位置7开始直到结束 |
4. 字符串的常用成员函数
4.1 长度与容量
获取字符串长度:
1 |
|
获取字符串容量:
每个 std::string 对象都有一个容量(capacity),表示它当前能够持有的最大字符数,而不需要重新分配内存。
1 |
|
输出示例:
1 | 初始容量: 15 |
注意: 容量可能因实现而异,并不保证它等于长度。
4.2 访问字符
对字符串中的字符操作,有如下方法, 切记需包含

使用索引访问单个字符:
1 |
|
使用 at() 函数(包含边界检查):
1 |
|
输出:
1 | 异常捕获: basic_string::at: __n (which is 10) >= this->size() (which is 5) |
4.3 转换大小写
C++ 标准库中的 std::toupper 和 std::tolower 可以用于转换字符的大小写。结合 std::transform,可以实现整个字符串的大小写转换。
转换为大写:
1 |
|
转换为小写:
1 |
|
4.4 其他有用的函数
**
empty()**:检查字符串是否为空。1
2
3
4std::string str;
if (str.empty()) {
std::cout << "字符串为空。" << std::endl;
}**
clear()**:清空字符串内容。1
2
3std::string str = "Clear me!";
str.clear();
std::cout << "str: " << str << std::endl; // 输出为空**
erase()**:删除字符串的部分内容。1
2
3std::string str = "Hello, World!";
str.erase(5, 7); // 从位置5开始,删除7个字符
std::cout << str << std::endl; // 输出: Hello!**
insert()**:在指定位置插入字符串或字符。1
2
3std::string str = "Hello World";
str.insert(5, ",");
std::cout << str << std::endl; // 输出: Hello, World**
replace()**:替换字符串的部分内容(前面已示例)。**
find_first_of(),find_last_of()**:查找字符集合中的任何一个字符。1
2
3std::string str = "apple, banana, cherry";
size_t pos = str.find_first_of(", ");
std::cout << "第一个逗号或空格的位置: " << pos << std::endl; // 输出: 5
5. 高级用法
5.1 字符串流(stringstream)
std::stringstream 是 C++ 标准库中第 <sstream> 头文件提供的一个类,用于在内存中进行字符串的读写操作,类似于文件流。
基本用法示例:
1 |
|
从字符串流中读取数据:
1 |
|
5.2 字符串与其他数据类型的转换
将其他类型转换为 std::string:
使用
std::to_string():1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() {
int num = 100;
double pi = 3.14159;
std::string str1 = std::to_string(num);
std::string str2 = std::to_string(pi);
std::cout << "str1: " << str1 << ", str2: " << str2 << std::endl;
// 输出: str1: 100, str2: 3.141590
return 0;
}
将 std::string 转换为其他类型:
使用字符串流:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main() {
std::string numStr = "256";
std::string piStr = "3.14";
int num;
double pi;
std::stringstream ss1(numStr);
ss1 >> num;
std::stringstream ss2(piStr);
ss2 >> pi;
std::cout << "num: " << num << ", pi: " << pi << std::endl;
// 输出: num: 256, pi: 3.14
return 0;
}使用
std::stoi(),std::stod()等函数(C++11 及以上):1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() {
std::string numStr = "256";
std::string piStr = "3.14";
int num = std::stoi(numStr);
double pi = std::stod(piStr);
std::cout << "num: " << num << ", pi: " << pi << std::endl;
// 输出: num: 256, pi: 3.14
return 0;
}
5.3 正则表达式与字符串匹配
C++ 标准库提供了 <regex> 头文件,用于支持正则表达式。
关于正则表达式的规则可以参考菜鸟教程文档https://www.runoob.com/regexp/regexp-syntax.html
基本用法示例:
1 |
|
输出:
1 | 5个字母的单词有: |
说明:
\b匹配单词边界。\w{5}匹配恰好5个字母的单词。
注意: 使用原始字符串字面值(R"()")以简化正则表达式的编写。
6. 字符串与 C 风格字符串的转换
6.1 从 C 风格字符串转换为 std::string
通过 std::string 的构造函数,可以轻松将 C 风格字符串转换为 std::string。
1 |
|
6.2 从 std::string 转换为 C 风格字符串
使用 c_str() 成员函数,可以获取 C 风格字符串指针。
1 |
|
注意: 返回的指针是只读的,且指向的内存由 std::string 管理,确保在 std::string 对象有效期间使用。
7. 示例项目
示例项目1:简易文本分析器
需求分析:
创建一个程序,接受用户输入的一段文本,并提供以下功能:
- 统计单词数量
- 统计每个单词出现的次数
- 查找指定单词的出现次数
- 输出最长的单词
代码实现:
1 |
|
运行示例:
1 | 请输入一段文本(结束请输入Ctrl+D/Ctrl+Z): |
代码解析:
- 读取用户输入的文本:使用
std::ostringstream和std::getline读取用户输入的多行文本,直到用户输入结束(Ctrl+D 或 Ctrl+Z)。 - 分割单词并统计:
- 使用
std::stringstream将文本分割为单词。 - 使用
std::map存储每个单词出现的次数。 - 计算总单词数和最长单词。
- 使用
- 查找指定单词:用户输入要查找的单词,程序查找并输出出现次数。
示例项目2:用户输入验证工具
需求分析:
编写一个程序,接受用户输入的电子邮件地址,并验证其格式是否正确。简单的验证标准:
- 包含一个
@符号 @后面有一个.符号- 不包含空格
代码实现:
1 |
|
运行示例:
1 | 请输入您的电子邮件地址: user@example.com |
1 | 请输入您的电子邮件地址: userexample.com |
代码解析:
- **定义验证函数
isValidEmail**:- 使用正则表达式
(\w+)(\.?\w+)*@(\w+)(\.\w+)+来匹配基本的邮箱格式。 - 该正则表达式匹配如下部分:
- 用户名部分:由字母数字字符组成,可以包含点号。
@符号。- 域名部分:由字母数字字符组成,至少包含一个点号后跟字母数字字符。
- 使用正则表达式
- 主函数:
- 提示用户输入邮箱地址。
- 调用
isValidEmail函数进行验证,并输出结果。
注意: 这个正则表达式只是一个基础的验证,实际应用中可能需要更复杂的正则表达式来处理更多的邮件格式。