C++ 中的 string
容器详细总结
1. 概述
C++ 中的 string
是标准模板库(STL)中一个用于处理字符序列的类。相较于 C 语言中的字符数组,string
提供了更丰富和安全的功能,可以轻松进行字符串的创建、修改和操作。string
是 C++ 标准库中的一个重要部分,广泛用于各种需要处理文本的程序中。本篇文章将详细总结 C++ 中的 string
容器,涵盖其基本使用方法、成员函数、与 C 风格字符串的相互转换、高级功能及其在实际应用中的一些优化技巧。
2. string
类的定义与基本使用
2.1 string
类的引入
C++ 中的 string
定义在 <string>
头文件中,要使用 string
需要包含相应的头文件并且使用 std
命名空间。
cpp
#include <string>
#include <iostream>
int main() {
std::string str = "Hello, World!";
std::cout << str << std::endl;
return 0;
}
在上面的代码中,通过 #include <string>
引入了 string
类,并在 std
命名空间下使用 string
,它表示一个标准的字符串类对象,可以直接对字符串进行多种操作。
2.2 string
的基本功能
-
初始化 :可以通过多种方式初始化
string
对象。cppstd::string str1 = "Hello"; std::string str2("Hello"); std::string str3(5, 'A'); // "AAAAA" std::string str4(str1); // 拷贝构造 std::string str5 = str1 + " World!"; // 字符串拼接
-
输出与输入 :可以通过
std::cout
和std::cin
对string
对象进行输出与输入操作。cppstd::cout << str1 << std::endl; std::cin >> str2; // 读入一个字符串,不包含空格部分
-
字符串拼接 :
+
操作符可以用于将两个string
对象或string
对象与 C 字符串拼接。cppstd::string str6 = str1 + " World";
3. string
的成员函数与操作
C++ 中的 string
类提供了大量的成员函数来对字符串进行操作,包括获取长度、查找子串、替换、插入、删除等。下面对这些常用成员函数进行详细总结。
3.1 大小和容量相关函数
-
size()
或length()
:返回字符串的长度。cppstd::string str = "Hello, World!"; std::cout << "Length: " << str.size() << std::endl;
-
capacity()
:返回当前分配的存储空间,可以存储的字符数量。cppstd::cout << "Capacity: " << str.capacity() << std::endl;
-
resize()
:改变字符串的大小,可以增大或减小。cppstr.resize(5); // 现在 str 变为 "Hello"
-
clear()
:清空字符串的内容,使其长度变为 0。cppstr.clear();
-
empty()
:判断字符串是否为空。cppif (str.empty()) { std::cout << "String is empty" << std::endl; }
3.2 访问字符
-
operator[]
和at()
:用于访问字符串中指定位置的字符。cppchar c1 = str[0]; char c2 = str.at(1);
其中,
at()
函数带有边界检查,如果索引超出范围会抛出out_of_range
异常,而operator[]
不做边界检查。
3.3 修改字符串
-
append()
和operator+=
:用于在字符串的末尾追加内容。cppstr.append("!!!"); // str 变为 "Hello, World!!!!" str += " Hello again"; // str 变为 "Hello, World!!!! Hello again"
-
insert()
:在指定位置插入字符串。cppstr.insert(5, "123"); // 在位置 5 插入 "123",str 变为 "Hello123, World!!!! Hello again"
-
erase()
:删除字符串中的字符。cppstr.erase(5, 3); // 从位置 5 开始删除 3 个字符
-
replace()
:替换字符串中的字符。cppstr.replace(0, 5, "Hi"); // 将前 5 个字符替换为 "Hi"
3.4 查找与子串
-
find()
:查找子字符串在当前字符串中的位置。cppsize_t pos = str.find("World"); if (pos != std::string::npos) { std::cout << "Found at: " << pos << std::endl; }
find()
返回子字符串的起始位置,如果未找到则返回std::string::npos
。 -
rfind()
:从字符串末尾开始查找子串。cppsize_t pos = str.rfind("Hello");
-
substr()
:返回字符串的子串。cppstd::string sub = str.substr(0, 5); // 获取从位置 0 开始的 5 个字符
3.5 比较字符串
-
compare()
:用于比较两个字符串。cppstd::string str1 = "Hello"; std::string str2 = "World"; if (str1.compare(str2) == 0) { std::cout << "Strings are equal" << std::endl; } else { std::cout << "Strings are not equal" << std::endl; }
compare()
函数返回 0 表示相等,返回负值表示小于,正值表示大于。
4. string
与 C 风格字符串的互操作
C++ 的 string
与 C 风格的字符数组(char[]
或 char*
)之间可以方便地相互转换。
4.1 C 风格字符串转换为 string
可以通过直接赋值或构造函数将 C 风格字符串转换为 string
对象。
cpp
const char* cstr = "Hello, C";
std::string str = cstr;
4.2 string
转换为 C 风格字符串
-
c_str()
:返回指向字符串内容的const char*
指针。cppconst char* cstr = str.c_str();
使用
c_str()
时要小心,它返回的指针内容是只读的,不应该对其进行修改。
5. string
的迭代器与遍历
string
类提供了多种迭代器,包括普通迭代器、常量迭代器、反向迭代器等,可以方便地遍历字符串中的字符。
5.1 使用迭代器遍历字符串
-
普通迭代器:
cppfor (std::string::iterator it = str.begin(); it != str.end(); ++it) { std::cout << *it; }
-
常量迭代器:
cppfor (std::string::const_iterator it = str.cbegin(); it != str.cend(); ++it) { std::cout << *it; }
-
反向迭代器:
cppfor (std::string::reverse_iterator rit = str.rbegin(); rit != str.rend(); ++rit) { std::cout << *rit; }
6. 字符串处理的高级功能
6.1 正则表达式匹配
C++11 引入了对正则表达式的支持,可以使用 <regex>
头文件对字符串进行复杂的模式匹配。
cpp
#include <regex>
#include <string>
#include <iostream>
int main() {
std::string str = "abc123xyz";
std::regex pattern("[a-z]+[0-9]+[a-z]+");
if (std::regex_match(str, pattern)) {
std::cout << "String matches the pattern" << std::endl;
}
return 0;
}
6.2 转换大小写
C++ 标准库提供了一些函数可以用来转换字符串中的字符大小写,例如 std::toupper()
和 std::tolower()
。
cpp
#include <cctype>
#include <algorithm>
std::string str = "Hello, World!";
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
std::cout << str << std::endl; // 输出:HELLO, WORLD!
6.3 字符串流处理
C++ 提供了 std::stringstream
类,用于处理字符串的输入输出操作,类似于文件流,可以方便地进行字符串的格式化和解析。
cpp
#include <sstream>
std::string data = "100 200 300";
std::stringstream ss(data);
int a, b, c;
ss >> a >> b >> c;
std::cout << a << " " << b << " " << c << std::endl;
7. string
的内存管理与性能优化
7.1 内存分配与容量管理
string
类通常会为字符串预分配额外的存储空间,以减少频繁的内存分配操作。这种预分配的容量可以通过 capacity()
方法查看,而通过 reserve()
方法可以提前分配存储空间,从而提高性能。
cpp
std::string str;
str.reserve(100); // 预分配 100 个字符的存储空间
7.2 使用 shrink_to_fit()
减少内存使用
如果字符串占用的容量远大于其实际大小,可以使用 shrink_to_fit()
来减少内存占用。
cpp
str.shrink_to_fit();
7.3 避免不必要的字符串拷贝
在函数参数中,如果不需要对字符串进行修改,建议使用 const std::string&
来传递字符串,避免不必要的拷贝。
cpp
void printString(const std::string& str) {
std::cout << str << std::endl;
}
8. 总结
C++ 中的 string
容器是一个功能强大的类,提供了丰富的接口来处理各种字符串操作。从基础的字符串拼接、截取,到复杂的查找、替换以及正则匹配,string
类都能高效地实现。同时,string
的自动内存管理和 STL 特性,使得开发者能够更加方便地进行字符串操作而无需担心内存泄漏等问题。掌握 string
的各种操作和优化技巧,不仅可以编写出功能强大的代码,还能提高程序的执行效率和可维护性。在实际开发中,合理使用 string
及其成员函数,可以极大地简化字符串处理的复杂度,使得代码更简洁、更高效。