c++string

在 C++ 编程中,std::string 是处理字符串的核心工具。它封装了 C 风格字符串(以 \0 结尾的字符数组)的复杂性,提供了更安全、更高效的字符串操作方式。本文将从基础到进阶,全面解析 std::string 的使用方法,并通过大量示例帮助你快速掌握。


一、std::string 的优势

  1. 自动内存管理:不需要手动分配或释放内存,避免内存泄漏。
  2. 丰富的操作接口:支持拼接、查找、替换、删除等常见操作。
  3. 安全性 :提供越界检查(如 at() 方法)和异常处理。
  4. 兼容性: 可与 C 风格字符串无缝交互(如 c_str())。
  5. 动态扩展:根据需要自动调整内部存储容量。

二、std::string 的构造与初始化

1. 默认构造

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s1; // 创建空字符串
    cout << "s1: " << s1 << ", size: " << s1.size() << endl;
    return 0;
}

输出:

cpp 复制代码
s1: , size: 0

2. 拷贝构造

cpp 复制代码
string s2 = "Hello"; // 用字符串字面量初始化
string s3 = s2;      // 用另一个 string 对象初始化
cout << "s3: " << s3 << endl;

3. 子串构造

cpp 复制代码
string s4("Hello World", 6); // 从第 0 个字符开始取 6 个字符
cout << "s4: " << s4 << endl; // 输出 "Hello"

4. 填充构造

cpp 复制代码
string s5(5, 'A'); // 创建 5 个 'A' 组成的字符串
cout << "s5: " << s5 << endl; // 输出 "AAAAA"

三、基本操作

1. 赋值

cpp 复制代码
string s;
s = "New String"; // 使用 = 赋值
s.assign("Another String"); // 使用 assign 方法
s.assign("ABC", 3); // 从 "ABC" 的前 3 个字符赋值
cout << "s: " << s << endl;

2. 连接

cpp 复制代码
string s1 = "Hello";
string s2 = "World";
string s3 = s1 + " " + s2; // 使用 + 运算符
cout << "s3: " << s3 << endl; // 输出 "Hello World"

3. 比较

cpp 复制代码
if (s1 == s2) {
    cout << "s1 == s2" << endl;
} else {
    cout << "s1 != s2" << endl;
}

// 使用 compare 方法
int result = s1.compare(s2);
if (result < 0) cout << "s1 < s2" << endl;
else if (result == 0) cout << "s1 == s2" << endl;
else cout << "s1 > s2" << endl;

四、常用成员函数

1. 访问字符

cpp 复制代码
string s = "Hello";
cout << "s[0]: " << s[0] << endl; // 不检查越界
cout << "s.at(5): " << s.at(5) << endl; // 检查越界,越界抛出 out_of_range 异常

2. 查找

cpp 复制代码
string s = "Hello World";
size_t pos = s.find("World"); // 查找子串 "World"
if (pos != string::npos) {
    cout << "Found at position: " << pos << endl;
}

3. 替换

cpp 复制代码
s.replace(6, 5, "Universe"); // 从第 6 位开始替换 5 个字符
cout << "After replace: " << s << endl; // 输出 "Hello Universe"

4. 删除

cpp 复制代码
s.erase(6, 8); // 删除从第 6 位开始的 8 个字符
cout << "After erase: " << s << endl; // 输出 "Hello "

5. 插入

cpp 复制代码
s.insert(5, " Beautiful"); // 在第 5 位插入 " Beautiful"
cout << "After insert: " << s << endl; // 输出 "Hello Beautiful World"

6. 截取子串

cpp 复制代码
string sub = s.substr(6, 9); // 从第 6 位开始取 9 个字符
cout << "Substring: " << sub << endl; // 输出 "Beautiful"

五、性能优化技巧

1. 避免频繁修改字符串

cpp 复制代码
string s;
for (int i = 0; i < 1000; ++i) {
    s += to_string(i); // 频繁追加可能导致多次内存分配
}

优化:预分配足够内存:

cpp 复制代码
s.reserve(10000); // 预留 10000 字符的容量

2. 使用 c_str() 与 C 风格字符串交互

cpp 复制代码
const char* cstr = s.c_str(); // 返回以 '\0' 结尾的 C 风格字符串

六、常见问题与解决方案

1. 字符串拼接效率问题

问题 :频繁使用 += 可能导致多次内存分配。解决 :使用 reserve() 预分配内存,或一次性构建字符串。

2. 如何处理嵌入式 \0

std::string 可以包含嵌入式 \0,但 c_str() 会在第一个 \0 截断。需要手动处理。

3. 如何将数字转换为字符串?

使用 std::to_string()

cpp 复制代码
int num = 123;
string s = to_string(num);

4. 如何将字符串转换为数字?

使用 std::stoistd::stol 等:

cpp 复制代码
string s = "456";
int num = stoi(s);

七、实战示例

1. 统计字符串中的单词数量

cpp 复制代码
#include <sstream>
#include <iostream>
#include <string>
using namespace std;

int main() {
    string input = "Hello World from C++";
    istringstream iss(input);
    int count = 0;
    string word;
    while (iss >> word) {
        ++count;
    }
    cout << "Word count: " << count << endl;
    return 0;
}

2. 替换所有出现的子串

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

void replaceAll(string& s, const string& oldSub, const string& newSub) {
    size_t pos = 0;
    while ((pos = s.find(oldSub, pos)) != string::npos) {
        s.replace(pos, oldSub.size(), newSub);
        pos += newSub.size(); // 移动到新插入位置
    }
}

int main() {
    string s = "Hello Hello World";
    replaceAll(s, "Hello", "Hi");
    cout << "After replacement: " << s << endl; // 输出 "Hi Hi World"
    return 0;
}

八、总结

std::string 是 C++ 中处理字符串的核心工具,其设计兼顾了安全性、效率和灵活性。通过本文的学习,你应该已经掌握了以下内容:

  1. 构造与初始化:多种方式创建字符串。
  2. 基本操作:赋值、连接、比较等。
  3. 常用函数:查找、替换、删除、插入等。
  4. 性能优化:避免频繁修改字符串,合理使用内存预分配。
  5. 实战应用:字符串流处理、子串替换等。

建议 :多动手实践,尝试用 std::string 解决实际问题(如文件读取、数据解析等),逐步提升对字符串操作的熟练度。