[数据结构·C++语法] string 成员函数详解
C++ std::string 成员函数详解
std::string 是 C++ 标准库中用于处理字符串的类。它提供了丰富的成员函数,使其操作既方便又高效。本文档整理了 std::string 的常用成员函数,并提供了使用实例。
1. 构造函数 (Constructors)
用于创建 std::string 对象。
默认构造函数
创建一个空字符串。1
2
3
4
5
6
7
8
int main() {
std::string s;
std::cout << "空字符串: \"" << s << "\"" << std::endl;
return 0;
}
拷贝构造函数
用一个已有的 std::string 对象创建新对象。
1 |
|
C-风格字符串 (const char*) 构造
用一个 C-风格的字符串(以 \0 结尾)来初始化。1
2
3
4
5
6
7
8
9
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
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 |
|
迭代器构造
用一对迭代器指定的范围来初始化。1
2
3
4
5
6
7
8
9
10
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
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
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
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
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
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
int main() {
std::string s;
std::cout << "Max Size: " << s.max_size() << std::endl;
return 0;
}
resize()
改变字符串的长度。如果新长度更长,用指定字符(默认 \0)填充;如果更短,则截断。
1 |
|
capacity()
返回当前分配给字符串的存储空间大小(字节数)。1
2
3
4
5
6
7
8
9
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 |
|
clear()
清除字符串内容,使其变为空字符串(长度为 0)。1
2
3
4
5
6
7
8
9
10
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
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 |
|
5. 元素访问 (Element Access)
用于访问字符串中的单个字符。
operator[]
访问指定索引处的字符(不进行边界检查)。1
2
3
4
5
6
7
8
9
10
11
12
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
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 |
|
back() (C++11)
访问最后一个字符。
1 |
|
6. 修改器 (Modifiers)
用于修改字符串的内容。
operator+=
在字符串末尾追加内容。
1 |
|
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
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 |
|
pop_back() (C++11)
删除字符串的最后一个字符。1
2
3
4
5
6
7
8
9
10
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
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
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
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 |
|
7. 字符串操作 (String Operations)
c_str()
返回一个指向 C-风格字符串(以 \0 结尾)的 const char* 指针。
1 |
|
data()
返回指向字符串数据的 const char* 指针。在 C++11 之前,不保证以 \0 结尾;C++11 及之后,它与 c_str() 行为一致。1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 |
|
copy()
将字符串的一部分复制到 C-风格的字符数组中(不自动添加 \0)。
1 |
|
find()
查找子串或字符首次出现的位置。
1 |
|
rfind()
查找子串或字符最后一次出现的位置。
1 |
|
find_first_of() / find_last_of()
查找字符集中任意一个字符的首次/最后一次出现。
1 |
|
find_first_not_of() / find_last_not_of()
查找不在字符集中的任意一个字符的首次/最后一次出现。
1 |
|
compare()
比较字符串。
1 |
|
