C++ `std::string` 类核心成员函数及用法详解

  ​今天我将带大家全面梳理 C++ 标准库中 std::string 类的核心成员函数及其用法。std::string<string> 头文件提供的字符串类,封装了字符数组的底层细节,提供了丰富的接口来高效处理文本数据(如拼接、查找、修改等)。掌握这些成员函数,是熟练使用 std::string 的关键。

  ​由于 std::string 的成员函数较多(超过 100 个),我将聚焦于最常用、最实用的 30+ 个核心成员函数,按功能分类(构造与初始化、赋值与修改、访问与查询、子串与拼接、查找与替换、迭代与容量管理)逐一讲解,并附上代码示例。这些函数覆盖了 90% 以上的日常字符串操作需求。

一、构造与初始化:创建 string 对象的多种方式

std::string 提供了多种构造函数,支持从不同数据源初始化字符串(如空字符串、C 风格字符串、部分字符、重复字符等)。

1. 默认构造:创建空字符串
std::string s1; // 空字符串(size()=0,无分配内存或分配最小缓冲区)
std::cout << s1.size(); // 输出 0
2. 从 C 风格字符串构造(const char*)
const char* cstr = "Hello";
std::string s2(cstr); // 复制 cstr 的内容("Hello"),size()=5
std::cout << s2; // 输出 Hello
3. 从部分字符构造(指定起始位置和长度)
const char* cstr = "abcdef";
std::string s3(cstr, 3); // 取前 3 个字符("abc"),size()=3
std::string s4(cstr, 1, 3); // 从索引 1 开始取 3 个字符("bcd"),size()=3
4. 重复字符构造(指定字符和重复次数)
std::string s5(5, 'x'); // 生成 5 个 'x'("xxxxx"),size()=5
5. 拷贝构造(深拷贝另一个 string 对象)
std::string s6("Original");
std::string s7(s6); // 深拷贝 s6 的内容("Original"),s6 和 s7 独立
6. 移动构造(C++11,转移资源所有权)
std::string s8("Temporary");
std::string s9(std::move(s8)); // 转移 s8 的资源给 s9,s8 变为空(size()=0)

二、赋值与修改:更新 string 内容的核心操作

通过赋值运算符和成员函数,可以修改 std::string 的内容(如直接赋值、追加、插入、删除)。

1. 赋值运算符(=)
std::string s1;
s1 = "New Value"; // 直接赋值 C 风格字符串(size()=9)
s1 = std::string("Another"); // 赋值另一个 string 对象(size()=7)
2. 拼接与追加(+= 或 append)
std::string s2 = "Hello";
s2 += " ";       // 追加空格("Hello "),等价于 s2.append(" ");
s2 += "World";   // 追加 "World"("Hello World")
// 或显式调用 append
s2.append("!");  // 追加 "!"("Hello World!")
3. 插入内容(insert)

在指定位置插入字符或字符串:

std::string s3 = "abcde";
s3.insert(2, "123"); // 在索引 2 处插入 "123"(原索引 2 及之后后移),结果:"ab123cde"
s3.insert(0, 3, 'x'); // 在索引 0 处插入 3 个 'x'("xxxab123cde")
4. 删除内容(erase)

删除指定位置和长度的字符:

std::string s4 = "abcdefgh";
s4.erase(2, 3); // 从索引 2 开始删除 3 个字符(删除 "cde"),结果:"abfgh"
s4.erase(0, 1); // 删除索引 0 的 1 个字符(删除 'a'),结果:"bfgh"
5. 替换内容(replace)

替换指定位置的子串:

std::string s5 = "Hello World";
s5.replace(6, 5, "C++"); // 从索引 6 开始替换 5 个字符(原 "World"→"C++"),结果:"Hello C++"
6. 清空字符串(clear)
std::string s6 = "Content";
s6.clear(); // 清空所有字符(size()=0,但容量可能不变)

三、访问与查询:获取字符或字符串信息

通过下标、成员函数直接访问字符,或查询字符串的属性(如长度、容量)。

1. 通过下标访问字符(operator[])
std::string s1 = "abc";
char c = s1[1]; // 获取索引 1 的字符 'b'(s1[1] = 'x' 可直接修改)
// 注意:operator[] 不检查越界(需自行确保索引合法)
2. 安全访问字符(at)
std::string s2 = "def";
try {
    char c = s2.at(2); // 获取索引 2 的字符 'f'(s2.at(3) 会抛出 std::out_of_range 异常)
    // s2.at(3); // 抛出异常!
} catch (const std::out_of_range& e) {
    std::cerr << "越界访问!";
}
3. 获取字符串长度(size/length)
std::string s3 = "Hello";
std::cout << s3.size();  // 输出 5(字符数,不含 '\0')
std::cout << s3.length(); // 等价于 size(),输出 5
4. 判断是否为空(empty)
std::string s4;
if (s4.empty()) { // 等价于 s4.size() == 0
    std::cout << "字符串为空";
}
5. 获取当前容量(capacity)
std::string s5;
std::cout << s5.capacity(); // 输出当前分配的缓冲区大小(可能为 0 或实现定义的最小值)
s5.reserve(100); // 预分配 100 字节后,capacity() >= 100

四、子串与拼接:提取或合并字符串片段

通过子串操作和拼接函数,可以灵活处理字符串的局部内容或合并多个字符串。

1. 提取子串(substr)
std::string s1 = "abcdefgh";
std::string sub1 = s1.substr(2, 3); // 从索引 2 开始取 3 个字符("cde")
std::string sub2 = s1.substr(5);    // 从索引 5 开始取到末尾("fgh")
2. 拼接字符串(+ 或 append)

虽然 + 运算符不是 std::string 的成员函数(而是重载的全局运算符),但它是拼接的常用方式:

std::string s2 = "Hello";
std::string s3 = "World";
std::string s4 = s2 + " " + s3; // 拼接结果:"Hello World"
// 等价于 s2.append(" ").append(s3);

五、查找与替换:定位与修改特定内容

通过查找函数定位目标(如子串、字符),再结合替换或删除操作实现文本处理。

1. 查找子串/字符(find/rfind)
std::string s1 = "abcabc";
size_t pos1 = s1.find("bc");  // 首次出现的位置(索引 1),未找到返回 std::string::npos
size_t pos2 = s1.rfind("bc"); // 反向查找(最后一次出现的位置,索引 4)
if (pos1 != std::string::npos) {
    std::cout << "找到子串,位置:" << pos1;
}
2. 查找字符(find_first_of/find_last_of)

查找任意一个指定字符集中的字符:

std::string s2 = "hello123";
size_t pos3 = s2.find_first_of("123"); // 第一个数字字符的位置(索引 5,'1')
size_t pos4 = s2.find_last_of("aeiou"); // 最后一个元音字母的位置(索引 4,'o')
3. 替换子串(replace,已在修改部分示例)
std::string s3 = "I love C";
s3.replace(7, 1, "C++"); // 从索引 7 开始替换 1 个字符('C'→'C++'),结果:"I love C++"

六、迭代与容量管理:遍历与性能优化

通过迭代器遍历字符串,或通过容量函数优化内存分配。

1. 迭代器支持(范围 for 或标准迭代器)
std::string s1 = "abc";
// 范围 for 循环(C++11)
for (char c : s1) {
    std::cout << c << " "; // 输出 a b c
}
// 标准迭代器
for (auto it = s1.begin(); it != s1.end(); ++it) {
    std::cout << *it << " "; // 输出 a b c
}
2. 预分配容量(reserve)

减少频繁追加时的内存重新分配:

std::string s2;
s2.reserve(1000); // 预分配 1000 字节的缓冲区
for (int i = 0; i < 100; ++i) {
    s2 += "log_entry_" + std::to_string(i) + "\n"; // 无需多次扩容
}
3. 调整大小(resize)

修改字符串的字符数(填充或截断):

std::string s3 = "hello";
s3.resize(8, 'x'); // 扩展到 8 字符,不足部分填充 'x'("helloxxx")
s3.resize(3);      // 截断到 3 字符("hel")
4. 收缩容量(shrink_to_fit,C++11)

释放未使用的缓冲区内存(非强制,但通常有效):

std::string s4 = "short";
s4.reserve(1000); // 容量可能变为 1000
s4.shrink_to_fit(); // 请求将容量调整为与 size() 一致(通常成功)

七、其他实用成员函数

1. 比较字符串(compare)

operator== 更灵活(支持部分比较和返回详细结果):

std::string s1 = "apple";
std::string s2 = "banana";
int res = s1.compare(s2); // 返回负数(s1 < s2 按字典序)
if (res == 0) { /* 相等 */ } else if (res < 0) { /* s1 < s2 */ } else { /* s1 > s2 */ }
2. 获取 C 风格字符串(c_str/data)
std::string s3 = "C++";
const char* cstr = s3.c_str(); // 返回 const char*(不可修改,以 '\0' 结尾)
// C++17 后 data() 也保证以 '\0' 结尾

总结:掌握这些成员函数,轻松应对 90% 的字符串需求

  ​以上是 std::string 最核心的 30+ 个成员函数及用法示例,覆盖了构造、赋值、访问、修改、查找、迭代等全部基础与进阶场景。实际开发中,建议根据需求选择最合适的函数(比如频繁追加用 reserve 优化,查找用 find,子串提取用 substr)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两圆相切

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值