C++ std::string 成员函数详解

std::string 是 C++ 标准库中用于处理字符串的类。它提供了丰富的成员函数,使其操作既方便又高效。本文档整理了 std::string 的常用成员函数,并提供了使用实例。

1. 构造函数 (Constructors)

用于创建 std::string 对象。

默认构造函数

创建一个空字符串。

1
2
3
4
5
6
7
8
#include <iostream>
#include <string>

int main() {
std::string s;
std::cout << "空字符串: \"" << s << "\"" << std::endl;
return 0;
}

拷贝构造函数

用一个已有的 std::string 对象创建新对象。

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main() {
std::string s1 = "Hello";
std::string s2(s1); // 拷贝构造
std::cout << "s2: " << s2 << std::endl;
return 0;
}

C-风格字符串 (const char*) 构造

用一个 C-风格的字符串(以 \0 结尾)来初始化。

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main() {
const char* c_str = "World";
std::string s(c_str);
std::cout << "s: " << s << std::endl;
return 0;
}

C-风格字符串 (const char*) + 长度 构造

用 C-风格字符串的前 n 个字符初始化。

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main() {
const char* c_str = "Hello World";
std::string s(c_str, 5); // 只取前 5 个 "Hello"
std::cout << "s: " << s << std::endl;
return 0;
}

填充构造

用 n 个重复的字符 c 来初始化。

1
2
3
4
5
6
7
8
#include <iostream>
#include <string>

int main() {
std::string s(5, 'A'); // "AAAAA"
std::cout << "s: " << s << std::endl;
return 0;
}

迭代器构造

用一对迭代器指定的范围来初始化。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>
#include <vector>

int main() {
std::vector<char> vec = {'a', 'b', 'c', 'd', 'e'};
std::string s(vec.begin(), vec.end());
std::cout << "s: " << s << std::endl;
return 0;
}

2. 赋值 (Assignment)

用于给 std::string 对象赋新值。

operator=

最常用的赋值操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>

int main() {
std::string s1;
std::string s2 = "Hello";

s1 = s2; // 赋 string
std::cout << "s1: " << s1 << std::endl;

s1 = "World"; // 赋 C-string
std::cout << "s1: " << s1 << std::endl;

s1 = 'A'; // 赋 char
std::cout << "s1: " << s1 << std::endl;
return 0;
}

assign()

功能更丰富的赋值函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <string>

int main() {
std::string s;
std::string base = "Use this string";

// 1. 赋 n 个字符
s.assign(5, '*'); // "*****"
std::cout << "s: " << s << std::endl;

// 2. 赋另一个 string
s.assign(base); // "Use this string"
std::cout << "s: " << s << std::endl;

// 3. 赋另一个 string 的子串
s.assign(base, 4, 4); // 从索引4开始,取4个 "this"
std::cout << "s: " << s << std::endl;

// 4. 赋 C-string
s.assign("New content");
std::cout << "s: " << s << std::endl;

// 5. 赋 C-string 的前n个字符
s.assign("Partial", 4); // "Part"
std::cout << "s: " << s << std::endl;

return 0;
}

3. 迭代器 (Iterators)

用于遍历字符串中的字符,提供类似STL容器的接口。

begin() / end()

返回指向字符串开头和结尾(末尾元素的下一个位置)的正向迭代器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
for(std::string::iterator it = s.begin(); it != s.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;

// C++11 范围 for (内部使用了 begin 和 end)
for(char c : s) {
std::cout << c << " ";
}
std::cout << std::endl;
return 0;
}

rbegin() / rend()

返回指向字符串末尾和开头(首个元素的前一个位置)的反向迭代器。

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
for(std::string::reverse_iterator it = s.rbegin(); it != s.rend(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}

(同样有 cbegin, cend, crbegin, crend 作为 const 版本)

4. 容量 (Capacity)

用于管理字符串的存储空间。

size() / length()

返回字符串中的字符数。两者功能完全相同。

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
std::cout << "Size: " << s.size() << std::endl;
std::cout << "Length: " << s.length() << std::endl;
return 0;
}

max_size()

返回字符串可能达到的最大长度。

1
2
3
4
5
6
7
8
#include <iostream>
#include <string>

int main() {
std::string s;
std::cout << "Max Size: " << s.max_size() << std::endl;
return 0;
}

resize()

改变字符串的长度。如果新长度更长,用指定字符(默认 \0)填充;如果更短,则截断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";

// 增长,用 '!' 填充
s.resize(10, '!');
std::cout << "s (resized to 10): " << s << std::endl; // "Hello!!!!!"

// 缩短
s.resize(5);
std::cout << "s (resized to 5): " << s << std::endl; // "Hello"
return 0;
}

capacity()

返回当前分配给字符串的存储空间大小(字节数)。

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
std::cout << "Size: " << s.size() << std::endl;
std::cout << "Capacity: " << s.capacity() << std::endl;
return 0;
}

reserve()

请求为字符串预留至少 n 个字符的存储空间。

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>

int main() {
std::string s;
std::cout << "Default capacity: " << s.capacity() << std::endl;

s.reserve(100); // 预留空间
std::cout << "Capacity after reserve: " << s.capacity() << std::endl;
return 0;
}

clear()

清除字符串内容,使其变为空字符串(长度为 0)。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
std::cout << "s: " << s << std::endl;
s.clear();
std::cout << "s after clear: \"" << s << "\"" << std::endl;
return 0;
}

empty()

检查字符串是否为空(长度是否为 0)。

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>

int main() {
std::string s1;
std::string s2 = "Hello";

std::cout << "s1 is empty: " << std::boolalpha << s1.empty() << std::endl;
std::cout << "s2 is empty: " << std::boolalpha << s2.empty() << std::endl;
return 0;
}

shrink_to_fit() (C++11)

请求减少 capacity()size(),释放未使用的内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

int main() {
std::string s;
s.reserve(100);
s = "Hello";
std::cout << "Capacity before: " << s.capacity() << std::endl;

s.shrink_to_fit(); // 请求释放多余内存

std::cout << "Capacity after: " << s.capacity() << std::endl;
std::cout << "Size: " << s.size() << std::endl;
return 0;
}

5. 元素访问 (Element Access)

用于访问字符串中的单个字符。

operator[]

访问指定索引处的字符(不进行边界检查)。

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
std::cout << "Char at 0: " << s[0] << std::endl; // 'H'

// 修改
s[0] = 'J';
std::cout << "s: " << s << std::endl; // "Jello"
return 0;
}

at()

访问指定索引处的字符(进行边界检查,越界会抛出 std::out_of_range 异常)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
#include <stdexcept>

int main() {
std::string s = "Hello";
try {
std::cout << "Char at 1: " << s.at(1) << std::endl; // 'e'

// 修改
s.at(1) = 'a';
std::cout << "s: " << s << std::endl; // "Hallo"

// 尝试越界
std::cout << s.at(10) << std::endl;

} catch (const std::out_of_range& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}

front() (C++11)

访问第一个字符。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
std::cout << "First char: " << s.front() << std::endl;
s.front() = 'Y';
std::cout << "s: " << s << std::endl; // "Yello"
return 0;
}

back() (C++11)

访问最后一个字符。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
std::cout << "Last char: " << s.back() << std::endl;
s.back() = 'p';
std::cout << "s: " << s << std::endl; // "Hellp"
return 0;
}

6. 修改器 (Modifiers)

用于修改字符串的内容。

operator+=

在字符串末尾追加内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
s += " World"; // 追加 C-string
std::cout << "s: " << s << std::endl;

std::string s2 = "!";
s += s2; // 追加 string
std::cout << "s: " << s << std::endl;

s += '!'; // 追加 char
std::cout << "s: " << s << std::endl;
return 0;
}

append()

功能更丰富的追加函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>

int main() {
std::string s = "File";
std::string ext = ".txt";

// 1. 追加 string
s.append(ext);
std::cout << "s: " << s << std::endl; // "File.txt"

// 2. 追加 string 的子串
s.append(" (backup)", 0, 8); // " (backup"
std::cout << "s: " << s << std::endl; // "File.txt (backup"

// 3. 追加 C-string
s.append(" - Final");
std::cout << "s: " << s << std::endl;

// 4. 追加 n 个字符
s.append(3, '!'); // "!!!"
std::cout << "s: " << s << std::endl;
return 0;
}

push_back()

在字符串末尾追加一个字符。这是您提到的类线性表函数。

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
s.push_back(' ');
s.push_back('W');
s.push_back('o');
std::cout << "s: " << s << std::endl; // "Hello Wo"
return 0;
}

pop_back() (C++11)

删除字符串的最后一个字符。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
std::cout << "s: " << s << std::endl;
s.pop_back();
std::cout << "s after pop_back: " << s << std::endl; // "Hell"
return 0;
}

insert()

在指定位置插入内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>

int main() {
std::string s = "Hello World";

// 1. 在索引 6 处插入 string
s.insert(6, "Beautiful ");
std::cout << "s: " << s << std::endl; // "Hello Beautiful World"

// 2. 在索引 0 处插入 C-string
s.insert(0, "Say: ");
std::cout << "s: " << s << std::endl; // "Say: Hello Beautiful World"

// 3. 在索引 5 处插入 3 个 '!'
s.insert(5, 3, '!');
std::cout << "s: " << s << std::endl; // "Say: !!!Hello Beautiful World"

return 0;
}

erase()

删除指定位置和长度的字符,或一个范围内的字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>

int main() {
std::string s = "Hello, Beautiful World!";

// 1. 从索引 5 开始,删除 11 个字符 (", Beautiful")
s.erase(5, 11);
std::cout << "s: " << s << std::endl; // "Hello World!"

// 2. 删除迭代器指定的单个字符
std::string s2 = "abc";
s2.erase(s2.begin() + 1); // 删除 'b'
std::cout << "s2: " << s2 << std::endl; // "ac"
return 0;
}

replace()

替换字符串的一部分内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>

int main() {
std::string base = "This is a test string.";
std::string rep = "sample";

// 1. 从索引 10 开始,替换 4 个字符 ("test") 为 "sample"
base.replace(10, 4, rep);
std::cout << "base: " << base << std::endl; // "This is a sample string."

// 2. 从索引 0 开始,替换 4 个字符 ("This") 为 C-string "That"
base.replace(0, 4, "That");
std::cout << "base: " << base << std::endl; // "That is a sample string."

// 3. 从索引 12 开始,替换 6 个字符 ("sample") 为 3 个 '*'
base.replace(12, 6, 3, '*');
std::cout << "base: " << base << std::endl; // "That is a *** string."
return 0;
}

swap()

交换两个 std::string 对象的内容。

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>

int main() {
std::string s1 = "Hello";
std::string s2 = "World";

std::cout << "Before swap: s1=" << s1 << ", s2=" << s2 << std::endl;
s1.swap(s2);
std::cout << "After swap: s1=" << s1 << ", s2=" << s2 << std::endl;
return 0;
}

7. 字符串操作 (String Operations)

c_str()

返回一个指向 C-风格字符串(以 \0 结尾)的 const char* 指针。

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>
#include <cstdio> // for printf

int main() {
std::string s = "Hello";

// c_str() 用于需要 (const char*) 的 C 风格函数
printf("C-style output: %s\n", s.c_str());
return 0;
}

data()

返回指向字符串数据的 const char* 指针。在 C++11 之前,不保证以 \0 结尾;C++11 及之后,它与 c_str() 行为一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
const char* p = s.data();

// 打印前 5 个字符
for(size_t i = 0; i < s.size(); ++i) {
std::cout << p[i];
}
std::cout << std::endl;
return 0;
}

substr()

返回一个新的 std::string 对象,它是原字符串的子串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

int main() {
std::string s = "Hello, World!";

// 1. 从索引 7 开始到末尾
std::string s1 = s.substr(7);
std::cout << "s1: " << s1 << std::endl; // "World!"

// 2. 从索引 0 开始,取 5 个字符
std::string s2 = s.substr(0, 5);
std::cout << "s2: " << s2 << std::endl; // "Hello"
return 0;
}

copy()

将字符串的一部分复制到 C-风格的字符数组中(不自动添加 \0)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

int main() {
std::string s = "Hello";
char buffer[10] = {0}; // 初始化为 0

// 从 s 的索引 0 开始,复制 5 个字符到 buffer
s.copy(buffer, 5, 0);

// buffer[5] = '\0'; // copy 不会自动添加,但我们已初始化

std::cout << "Buffer: " << buffer << std::endl; // "Hello"
return 0;
}

find()

查找子串或字符首次出现的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>

int main() {
std::string s = "Hello World, Hello Universe";
std::string to_find = "Hello";

// 1. 查找 "Hello"
size_t pos1 = s.find(to_find);
if (pos1 != std::string::npos) {
std::cout << "'Hello' found at index: " << pos1 << std::endl; // 0
}

// 2. 从索引 1 之后开始查找 "Hello"
size_t pos2 = s.find(to_find, 1);
if (pos2 != std::string::npos) {
std::cout << "'Hello' found again at index: " << pos2 << std::endl; // 13
}

// 3. 查找字符 'W'
size_t pos3 = s.find('W');
if (pos3 != std::string::npos) {
std::cout << "'W' found at index: " << pos3 << std::endl; // 6
}
return 0;
}

rfind()

查找子串或字符最后一次出现的位置。

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>

int main() {
std::string s = "Hello World, Hello Universe";

size_t pos = s.rfind("Hello");
if (pos != std::string::npos) {
std::cout << "Last 'Hello' found at index: " << pos << std::endl; // 13
}
return 0;
}

find_first_of() / find_last_of()

查找字符集任意一个字符的首次/最后一次出现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>

int main() {
std::string s = "Hello World!";
std::string vowels = "aeiouAEIOU";

// 查找第一个元音字母
size_t pos1 = s.find_first_of(vowels);
if (pos1 != std::string::npos) {
std::cout << "First vowel '" << s[pos1] << "' found at index: " << pos1 << std::endl; // 'e' at 1
}

// 查找最后一个元音字母
size_t pos2 = s.find_last_of(vowels);
if (pos2 != std::string::npos) {
std::cout << "Last vowel '" << s[pos2] << "' found at index: " << pos2 << std::endl; // 'o' at 7
}
return 0;
}

find_first_not_of() / find_last_not_of()

查找不在字符集中的任意一个字符的首次/最后一次出现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>

int main() {
std::string s = "!!!Hello!!!";
std::string punctuation = "!";

// 查找第一个不是 '!' 的字符
size_t pos = s.find_first_not_of(punctuation);
if (pos != std::string::npos) {
std::cout << "First non-'!' char '" << s[pos] << "' found at: " << pos << std::endl; // 'H' at 3
}
return 0;
}

compare()

比较字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>

int main() {
std::string s1 = "Hello";
std::string s2 = "Hello";
std::string s3 = "World";

// 1. s1 == s2
if (s1.compare(s2) == 0) {
std::cout << "s1 and s2 are equal" << std::endl;
}

// 2. s1 < s3
if (s1.compare(s3) < 0) {
std::cout << "s1 is less than s3" << std::endl;
}

// 3. 比较 s1 和 "Hell" (s1 > "Hell")
if (s1.compare("Hell") > 0) {
std::cout << "s1 is greater than 'Hell'" << std::endl;
}

// 更简单的方式 (重载了操作符)
if (s1 == s2) {
std::cout << "(Operator) s1 == s2" << std::endl;
}
if (s1 < s3) {
std::cout << "(Operator) s1 < s3" << std::endl;
}

return 0;
}