目录
一、引言
在C++编程体系中, string 类是处理文本数据的核心组件。相较于传统C风格以 \0 结尾的字符数组, string 类通过封装大量实用函数,不仅避免了手动内存管理的繁琐与安全隐患,还提供了丰富的操作方式,极大提升了字符串处理的便捷性和安全性。本文将对 string 库中常用函数进行深度剖析,结合大量代码示例与注意事项,帮助开发者全面掌握其使用技巧。
二、基础准备:头文件与命名空间
使用 string 类前,必须包含 <string> 头文件,并处理命名空间。常见方式有两种:
cpp
// 方式一:引入整个std命名空间
#include <string>
using namespace std;
// 方式二:显式指定std命名空间
#include <string>
std::string str;
注意:引入整个 std 命名空间可能引发命名冲突(如自定义函数名与 std 中函数名重复),推荐在小型项目或明确无冲突风险时使用;显式指定命名空间更安全,适合大型项目。
三、string对象的创建与初始化(基础)
3.1 直接初始化
cpp
// 字面量初始化
string str1 = "Hello, C++";
string str2("This is a string");
// 拷贝初始化
string str3 = str1;
3.2 动态初始化(空字符串)
cpp
string emptyStr; // 长度为0的字符串
3.3 基于字符数组初始化
cpp
char cArray[] = {'H', 'e', 'l', 'l', 'o', '\0'};
string strFromArray(cArray);
3.4 重复字符初始化
cpp
string repeated(5, 'a'); // 生成字符串 "aaaaa"
四、核心函数详解
4.1 字符串长度相关
4.1.1 length() 和 size()
cpp
string str = "Programming";
size_t len1 = str.length(); // 11
size_t len2 = str.size(); // 11
注意:
- length() 和 size() 功能完全相同, size() 是为了与STL容器接口统一。
- 返回值类型 size_t 是无符号整数,与负数比较时需格外小心,例如:
cpp
string str = "test";
if (str.length() > -1) { // 永远为真,-1会隐式转换为超大无符号数
// ...
}
4.1.2 capacity() 和 reserve()
capacity() 返回当前字符串已分配的内存空间(以字符为单位); reserve() 用于预分配内存,减少动态扩容次数。
cpp
string str;
cout << "初始容量: " << str.capacity() << endl; // 可能是15或其他默认值
str.reserve(100); // 预分配100个字符的空间
cout << "调整后容量: " << str.capacity() << endl; // 至少为100
注意: reserve() 不改变字符串实际长度,仅影响内存分配;若传入参数小于当前容量, reserve() 通常不执行操作。
4.2 字符串拼接
4.2.1 + 运算符与 += 复合赋值
cpp
string str1 = "Hello";
string str2 = "World";
string result = str1 + ", " + str2; // "Hello, World"
str1 += ", C++"; // 等价于 str1 = str1 + ", C++"
4.2.2 append() 函数(不咋好有,不推荐)
cpp
string str = "Apple";
// 追加字符串
str.append(" and Banana"); // "Apple and Banana"
// 追加子串(从源字符串第3个位置开始,取4个字符)
str.append("Cherry", 3, 4); // "Apple and Bananarry"
// 追加字符数组
char arr[] = {'!', '\0'};
str.append(arr); // "Apple and Bananarry!"
注意: append() 支持多种参数类型,使用时需确保索引和长度合法,避免越界。
4.3 字符串查找
4.3.1 find() 系列函数
cpp
string str = "banana";
// 查找子串首次出现位置
size_t pos1 = str.find("na"); // 2
// 查找字符最后出现位置
size_t pos2 = str.rfind('a'); // 5
// 查找字符集中任意字符首次出现位置
size_t pos3 = str.find_first_of("aeiou"); // 1
// 查找字符集中未出现的字符首次位置
size_t pos4 = str.find_first_not_of("abn"); // string::npos
注意:
- 所有查找函数未找到时均返回 string::npos ,建议使用 if (pos != string::npos) 进行判断。
- find_first_of() 和 find_last_of() 匹配字符集中任意字符,而非整个集合。
4.4 子串提取
cpp
string str = "Hello, World";
// 提取从索引7开始,长度为5的子串
string sub = str.substr(7, 5); // "World"
// 若省略长度参数,提取到字符串末尾
string subAll = str.substr(7); // "World"
注意:起始索引不能超过字符串长度,否则行为未定义;长度参数过大时,会截取到字符串末尾。
4.5 字符串替换
4.5.1 replace() 函数
cpp
string str = "old text";
// 从索引4开始,替换4个字符
str.replace(4, 4, "new"); // "old new"
// 按子串替换(替换所有匹配项)
str = "apple apple";
str.replace(str.find("apple"), 5, "banana"); // "banana apple"
注意:若要替换所有匹配项,需循环调用 replace() ;替换操作可能改变字符串容量和迭代器状态。