简介
string 是 C++ 标准库中的一个类,定义在 <string> 头文件中,是一个动态大小的字符数组。
定义与构造
//要使用 string,你需要包含 <string> 头文件:
#include <string>
定义一个 string 可以使用几种不同的方式:
//默认构造:创建一个空字符串。
string s;
//使用字符串文字:创建一个字符串并初始化。
string s = "Hello, World!";
//使用字符数组:
const char* c_str = "Hello!";
string s(c_str);
//指定长度的字符串:创建一个长度为 n 的字符串,初始化为某个字符。
string s(5, 'a'); // "aaaaa"
基本操作
插入一个字符
使用s.insert()函数在s的k1号位置处插入一个字符c;和vector一样
int k1;
char c;
cin>>k1>>c;
s.insert(s.begin() + k1, c);
获取字符串长度
string s = "Hello";
int len = s.size(); // 或者 s.length(),返回字符串的长度
访问字符
char ch = s[1]; // 获取第二个字符,注意索引从 0 开始
char ch2 = s.at(1); // 或者使用 at(),当索引超出范围时会抛出异常
at()用法补充说明
at() 方法用于访问字符串中的指定位置的字符,且会进行边界检查。如果访问的索引超出了字符串的有效范围,它会抛出 std::out_of_range 异常。
at(1) 会访问字符串中的第二个字符(索引从 0 开始)。如果字符串的长度小于或等于 1,则会抛出异常。
相比于使用 operator[](即 s[1]),at() 方法提供了更安全的访问方式,因为它会在越界时抛出异常。
string s = "Hello";
char ch2 = s.at(1); // ch2 = 'e',因为 "Hello" 中的第二个字符是 'e'
对比 [] 和 at()
s[1] 可以直接访问索引为 1 的字符,但如果索引越界,不会抛出异常,而是返回一个未定义的行为。
string s = "Hi";
char ch = s[10]; // 未定义行为,如果越界访问,程序不会抛出异常
s.at(1) 则更安全,如果索引越界,程序会抛出异常,提醒开发者发生了错误。
string s = "Hi";
try {
char ch = s.at(10); // 会抛出 std::out_of_range 异常
} catch (const out_of_range& e) {
cout << "Out of range error: " << e.what() << endl;
}
/*
总结:
at():用于访问字符串中的字符,并且会检查越界,如果越界则抛出异常。
[]:可以访问字符,但不进行越界检查,可能导致未定义行为。
通常,建议在访问字符串字符时使用 at(),尤其在涉及到不确定长度的字符串时,能更好地避免潜在的错误。
*/
修改字符
s[0] = 'h'; // 修改第一个字符
字符串拼接
string s1 = "Hello";
string s2 = " World!";
string s3 = s1 + s2; // 拼接
s1.append(s2); // 使用 append() 方法
查找字符串find
int pos = s.find("lo"); // 返回子字符串首次出现的位置,如果没有找到返回 string::npos
//size_t pos = s.find("lo");
if (pos != string::npos) {
cout << "'lo' found at position " << pos << endl;
}
/*
string::npos 是 C++ 标准库中的一个常量,用于表示一个无效的字符串位置。它通常与 find()、rfind() 和类似的函数一起使用,以指示查找失败的情况。
*/
提取子字符串substr
string s2 = s.substr(0, 3); // 从位置 0 开始,提取 3 个字符 substr(pos, length)
删除字符
位置是迭代器的位置。和vector一样
数字表示
s.erase(1, 3); // 从位置 1 开始,删除 3 个字符 erase(pos, length)
迭代器表示
使用s.erase()函数删除s的k2号位置的字符。
s.erase(s.begin() + k2);
替换字符
s.replace(pos, len, s1);
s.replace(0, 5, "Hi"); // 从位置 0 开始,替换 5 个字符为 "Hi".在s的基础上修改
//或者结果赋值给一个新的string,命名为s1
string s1 = s.replace(0, 5, "Hi");
转换大小写
transform(s.begin(), s.end(), s.begin(), ::tolower); // 转小写
transform(s.begin(), s.end(), s.begin(), ::toupper); // 转大写
清空字符串
s.clear(); // 清空字符串内容
比较字符串
直接使用 > < == 进行比较(字典序)
if (s1 == s2) {
cout << "Strings are equal" << endl;
}
转换为C风格字符串
const char* cstr = s.c_str(); // 将 string 转为 C 风格字符串
整数转字符串
int x = 10;
string v = to_string(x);
字符串转整数
string s = "1234";
int num = stoi(s);
注意!stoi()只能用于字符串,对于字符char会报错。
字符转整数
方法 1:利用 ASCII 码计算
char c = '5';
int num = c - '0'; // '5' - '0' = 5
适用场景:
-
仅适用于
'0'到'9'的字符。 -
如果
c不是数字字符(如'a'),结果会是错误的('a' - '0' = 49)。
方法 2:先转成 string,再用 stoi()
char c = '5';
int num = stoi(string(1, c)); // 构造一个长度为 1 的 string
适用场景:
-
适用于任何
char,但比方法 1 稍慢。 -
如果
c不是数字字符(如'a'),stoi()会抛出std::invalid_argument异常。
方法 3:使用 istringstream(更通用)
#include <sstream>
char c = '5';
int num;
istringstream(string(1, c)) >> num;
适用场景:
-
适用于更复杂的转换(如十六进制字符
'A'转10)。 -
比
stoi()稍慢,但更灵活。
检查是否为空
if (s.empty()) {
cout << "String is empty" << endl;
}
//如果为空,返回true
序列反转
在 C++ 中,reverse() 是标准库 <algorithm> 头文件中的一个算法,用于反转容器中的元素顺序。它可以用来反转任何支持迭代器的容器(如 vector、string、deque 等)。
reverse() 将 [first, last) 范围内的元素顺序反转。即第一个元素与最后一个元素交换,第二个元素与倒数第二个元素交换,以此类推。
//基本语法
#include <algorithm>
void reverse(Iterator first, Iterator last);
//reverse()没有返回值,它直接修改原容器或序列
//故不用s.reverse(),而是直接reverse()
//string reversed = reverse(substr.begin(), substr.end());这是错误用法,没有返回值
string s = "Hello, World!";
reverse(s.begin(), s.end());//s.end()是最后一个元素的后一个位置
cout << "Reversed string: " << s << endl;
两个字符的反转
//两个字符的三种反转方式
string substr = s.substr(i, 2); // 获取长度为 2 的子字符串
string reversed = string(1, substr[1]) + substr[0]; // 反转该子字符串
string reversed = {substr[1], substr[0]};
reverse(substr.begin(), substr.end());
示例程序
#include <iostream>
#include <string>
using namespace std;
int main() {
// 创建字符串
string s = "Hello, World!";
// 输出字符串
cout << "Original string: " << s << endl;
// 获取长度
cout << "Length of string: " << s.size() << endl;
// 拼接字符串
string s2 = " How are you?";
string s3 = s + s2;
cout << "Concatenated string: " << s3 << endl;
// 查找子字符串
size_t pos = s.find("World");
if (pos != string::npos) {
cout << "'World' found at position: " << pos << endl;
}
// 提取子字符串
string sub = s.substr(7, 5); // "World"
cout << "Substring: " << sub << endl;
// 修改字符串
s[0] = 'h'; // 将 "Hello" 改为 "hello"
cout << "Modified string: " << s << endl;
// 清空字符串
s.clear();
cout << "String after clear: " << (s.empty() ? "Empty" : s) << endl;
return 0;
}
优点
-
自动管理内存:
string会自动管理内存分配和释放,不需要显式地处理内存分配。 -
便捷的操作:提供了许多方法,简化了字符串操作(如拼接、查找、替换等)。
-
可以与 C 风格字符串互操作:可以方便地将
string转换为 C 风格字符串(const char*)并与 C 函数一起使用。
总结
-
string是一个非常强大且灵活的字符串类,提供了多种方法来操作字符串。 -
它是 C++ 标准库的一部分,能够更安全和方便地操作字符串,避免了 C 风格字符串中的许多麻烦(如手动管理内存、缺乏边界检查等)。
-
string是 C++ 中处理字符串时的首选类型,尤其适合需要频繁操作字符串的场景。
597

被折叠的 条评论
为什么被折叠?



