1、string 基本概念
string
是 C++ 标准库的一部分,定义在 <string>
头文件中。它封装了动态分配的字符数组,可以方便地存储和操作文本。string
类本质上是一个模板类(std::basic_string<char>
),其模板参数通常是 char
,表示存储的是单字节字符。
类模板:在 C++ 中,类模板允许类在定义时可以通过参数化类型(模板参数)来支持不同的数据类型。这样,程序员可以使用相同的代码逻辑去处理不同类型的数据,而不必为每种类型写单独的类。
在 C++ 标准库中,
std::basic_string
是一个类模板。它被设计为能够处理不同类型的字符。类模板std::basic_string
使用模板参数指定字符串中字符的类型和其他相关信息。因此,std::basic_string
可以适应不同类型的字符。// C++ 标准库定义了以下别名 // char:表示单字节字符,用于普通的 ASCII 或 UTF-8 字符串。 typedef std::basic_string<char> std::string; // wchar_t:表示宽字符,用于宽字符编码的字符串,如 UCS-2 或 UTF-16。 typedef std::basic_string<wchar_t> std::wstring; // char16_t 和 char32_t:用于处理 UTF-16 和 UTF-32 编码的字符串。 typedef std::basic_string<char16_t> std::u16string; typedef std::basic_string<char32_t> std::u32string;
2、常见操作与方法
2.1、初始化与赋值
std::string s1 = "Hello";
std::string s2("World");
std::string s3(s1); // 使用另一个字符串初始化
std::string s4(5, 'A'); // 创建一个由5个字符 'A' 组成的字符串
std::string s5("Hello World!",5); //创建的字符串为 "Hello"
2.2、字符串拼接
可以使用 +
操作符或 append()
函数来拼接字符串。
std::string s1 = "Hello";
std::string s2 = " World";
std::string s3 = s1 + s2; // 拼接
s1.append("!"); // 结果是 "Hello!"
2.3、字符串访问与修改
通过下标 []
或 at()
可以访问和修改字符串中的字符。
std::string s = "Hello";
char c = s[1]; // 'e'
s[0] = 'h'; // 修改第一个字符,结果是 "hello"
at()
方法与 []
类似,但会进行越界检查:
try
{
char c = s.at(10); // 越界,抛出异常
}
catch (std::out_of_range& e)
{
std::cout << "Out of range!" << std::endl;
}
2.4、字符串长度
size()
和 length()
都可以用来获取字符串的长度。
std::string s = "Hello";
std::cout << s.size() << std::endl; // 输出 5
std::cout << s.length() << std::endl; // 输出 5
2.5、字符串容量
capacity()
函数返回当前 std::string
为其内容分配的存储空间(也称为容量)的大小。这个容量通常比字符串实际的字符数(即 size()
或 length()
返回的值)大,因为 std::string
会为未来的扩展保留额外的空间,从而减少频繁的内存分配操作。
#include <iostream>
#include <string>
int main()
{
std::string s = "Hello";
std::cout << "Size: " << s.size() << std::endl; // 实际字符数
std::cout << "Capacity: " << s.capacity() << std::endl; // 当前容量
s += ", World!"; // 拼接字符串,可能会导致容量增加
std::cout << "Size after append: " << s.size() << std::endl;
std::cout << "Capacity after append: " << s.capacity() << std::endl;
return 0;
}
reserve()
函数可以用来手动设置 std::string
的容量。通过调用 reserve()
,你可以为字符串的内容预留一定的内存空间,减少后续扩展时的内存分配操作。如果设置的容量小于当前容量,容量不会减少。
#include <iostream>
#include <string>
int main()
{
std::string s = "Hello";
std::cout << "Initial capacity: " << s.capacity() << std::endl;
s.reserve(50); // 手动预留 50 个字符的空间
std::cout << "Capacity after reserve: " << s.capacity() << std::endl;
return 0;
}
shrink_to_fit()
函数请求将 std::string
的容量缩减到与其内容的实际大小相匹配。它并不保证一定会减少容量,而是向实现发出一个优化内存使用的请求。
#include <iostream>
#include <string>
int main()
{
std::string s = "Hello, World!";
std::cout << "Capacity before shrink_to_fit: " << s.capacity() << std::endl;
s.shrink_to_fit(); // 请求缩小容量
std::cout << "Capacity after shrink_to_fit: " << s.capacity() << std::endl;
return 0;
}
2.6、字符串查找与子串
find()
用于查找子串的起始位置。如果未找到子串,返回std::string::npos
。substr()
用于提取子串。
std::string s = "Hello, World!";
std::size_t pos = s.find("World");
if (pos != std::string::npos)
{
std::cout << "Found at position: " << pos << std::endl;
}
std::string sub = s.substr(7, 5); // 提取从位置 7 开始,长度为 5 的子串,结果是 "World"
2.7、比较字符串
可以使用 ==
、!=
、<
、>
等操作符进行字符串比较。compare()
方法提供了更细粒度的比较方式。
std::string s1 = "Hello";
std::string s2 = "World";
if (s1 == s2)
{
std::cout << "Equal" << std::endl;
}
else
{
std::cout << "Not equal" << std::endl;
}
int result = s1.compare(s2); // 返回负数,表示 s1 小于 s2
2.8、插入与删除
insert()
可以在指定位置插入字符串。erase()
删除字符串中的部分内容。
std::string s = "Hello!";
s.insert(5, ", World"); // 在位置 5 插入 ", World",结果是 "Hello, World!"
s.erase(5, 7); // 从位置 5 开始删除 7 个字符,结果是 "Hello"
2.9、替换
replace()
用于替换字符串中的部分内容。
std::string s = "Hello, World!";
s.replace(7, 5, "C++"); // 从位置 7 开始替换 5 个字符为 "C++",结果是 "Hello, C++!"
2.10、迭代器
std::string s = "Hello";
for (std::string::iterator it = s.begin(); it != s.end(); ++it)
{
std::cout << *it << " "; // 输出每个字符
}
2.11、string 与 char* 的相互转换
string 转化为 char* 可以使用 c_str() 函数。
std::string s = "Hello";
const char* cstr = s.c_str(); // 转换为 C 风格字符串
char* 可以直接转化为 string。
2.12、空字符串
空字符串的长度为 0。可以用 empty()
方法判断字符串是否为空。
std::string s = "";
if (s.empty())
{
std::cout << "The string is empty" << std::endl;
}
使用 clear()
方法可以清空字符串,使字符串的长度变为 0,但是容量不会改变。