String类
string是C++的一个类类型(不是基本类型),用于处理字符串。相对的C中的字符串是字符数组。
1.头文件和命名空间
需要引用string、iostream、sstream、algorithm等STD库。
#include<string> //必须有的主要头文件
#include<iostream> //用于输入输出
#include<sstream> //用于字符串流
#include<algorithm> //算法操作
using namespace std;
2.构造函数
// 默认构造函数
string str1; // 空字符串
// 从C风格字符串构造
string str2("Hello"); // "Hello"
string str3 = "World"; // "World"
// 从另一个string构造
string str4(str2); // "Hello"
string str5 = str2; // "Hello"
// 从部分字符串构造
string str6("Hello World", 5); // "Hello" (前5个字符)
string str7(str2, 1, 3); // "ell" (从位置1开始,长度3)
// 重复字符构造
string str8(5, 'A'); // "AAAAA"
// 使用迭代器构造
string str9(str2.begin(), str2.end()); // "Hello"
// 使用初始化列表 (C++11)
string str10{'H', 'e', 'l', 'l', 'o'}; // "Hello"
3.基本操作
3.1 赋值操作
string s1, s2, s3;
// 赋值操作
s1 = "Hello"; // "Hello"
s2 = s1; // "Hello"
s3.assign("World"); // "World"
s3.assign(s1, 1, 3); // "ell" (从s1的位置1开始,长度3)
s3.assign(5, 'X'); // "XXXXX"
长度和容量
string s = "Hello";
cout << s.length() << endl; // 5
cout << s.size() << endl; // 5 (与length()相同)
cout << s.capacity() << endl; // 当前分配的存储空间大小
cout << s.max_size() << endl; // 最大可能长度
s.resize(10, '!'); // "Hello!!!!!"
s.resize(3); // "Hel"
s.reserve(100); // 预分配100字符的空间
s.shrink_to_fit(); // 减少容量以匹配大小(C++11)
访问字符
string s = "Hello";
// 使用下标运算符
char c1 = s[0]; // 'H'
s[1] = 'a'; // "Hallo"
// 使用at()函数(会检查边界)
char c2 = s.at(2); // 'l'
// s.at(10); // 抛出std::out_of_range异常
// 访问首尾字符
char first = s.front(); // 'H' (C++11)
char last = s.back(); // 'o' (C++11)
// 获取C风格字符串
const char* cstr = s.c_str(); // 以null结尾的C字符串
const char* data = s.data(); // 字符数组(C++17前可能不以null结尾)
3.2 字符串修改
追加
string s = "Hello";
s += " World"; // "Hello World"
s.append("!!!"); // "Hello World!!!"
s.push_back('?'); // "Hello World!!!?"
// 追加部分字符串
s.append("ABCDEF", 3); // 追加前3个字符 "ABC"
s.append(s, 0, 3); // 追加s的前3个字符
// 使用insert插入
s.insert(5, " C++"); // 在位置5插入 "Hello C++ World!!!?ABC"
删除
string s = "Hello World";
s.erase(5, 6); // "Hello" (从位置5删除6个字符)
s.erase(s.begin() + 2); // "Helo" (删除位置2的字符)
s.erase(s.begin() + 1, s.begin() + 3); // "Ho" (删除[1,3)的字符)
s.clear(); // 清空字符串
s = "Hello World";
s.pop_back(); // "Hello Worl" (C++11)
替换
string s = "Hello World";
s.replace(6, 5, "C++"); // "Hello C++" (从位置6开始,替换5个字符)
s.replace(s.begin(), s.begin() + 5, "Hi"); // "Hi World"
3.3 字符串查找
string s = "Hello World, Hello C++";
// find - 查找子串
size_t pos1 = s.find("Hello"); // 0
size_t pos2 = s.find("Hello", 1); // 13 (从位置1开始找)
size_t pos3 = s.find("Java"); // string::npos (未找到)
// rfind - 从后向前查找
size_t pos4 = s.rfind("Hello"); // 13
// find_first_of - 查找字符集中任意字符首次出现
size_t pos5 = s.find_first_of("aeiou"); // 1 ('e')
// find_last_of - 查找字符集中任意字符最后出现
size_t pos6 = s.find_last_of("aeiou"); // 17 ('+')
// find_first_not_of - 查找不在字符集中的字符首次出现
size_t pos7 = s.find_first_not_of("Helo "); // 5 ('W')
// find_last_not_of - 查找不在字符集中的字符最后出现
size_t pos8 = s.find_last_not_of("+C"); // 16 (' ')
3.4 子串操作
string s = "Hello World";
// substr - 获取子串
string sub1 = s.substr(6); // "World" (从位置6到结尾)
string sub2 = s.substr(0, 5); // "Hello" (从位置0开始,长度5)
string sub3 = s.substr(6, 100); // "World" (长度超过时取到结尾)
// string sub4 = s.substr(100); // 抛出std::out_of_range异常
// compare - 比较字符串
int cmp1 = s.compare("Hello"); // >0 (s > "Hello")
int cmp2 = s.compare(6, 5, "World"); // 0 (s从6开始的5个字符等于"World")
3.5 字符串比较
string s1 = "apple";
string s2 = "banana";
// 使用比较运算符
bool b1 = (s1 == s2); // false
bool b2 = (s1 != s2); // true
bool b3 = (s1 < s2); // true (字典序比较)
bool b4 = (s1 > s2); // false
bool b5 = (s1 <= s2); // true
bool b6 = (s1 >= s2); // false
// 与C字符串比较
bool b7 = (s1 == "apple"); // true
bool b8 = ("apple" == s1); // true (有重载运算符)
// 使用compare函数
int result = s1.compare(s2);
if (result < 0) cout << "s1 < s2" << endl;
else if (result > 0) cout << "s1 > s2" << endl;
else cout << "s1 == s2" << endl;
3.6 输入输出
// 从标准输入读取
string input;
cout << "Enter a string: ";
cin >> input; // 读取到空白字符为止
getline(cin, input); // 读取整行(包括空格)
// 清除输入缓冲区
cin.ignore(numeric_limits<streamsize>::max(), '\n');
// 输出
cout << "You entered: " << input << endl;
// 格式化输出
printf("C-style: %s\n", input.c_str());
// 使用stringstream
stringstream ss;
ss << "Number: " << 42 << " String: " << input;
string formatted = ss.str();
cout << formatted << endl;
3.7 字符串转换
数字转换
// 字符串转数字
string num_str = "123";
int num1 = stoi(num_str); // 123
double num2 = stod("3.14"); // 3.14
long num3 = stol("1000000"); // 1000000
// 带异常处理
try {
int num = stoi("abc"); // 抛出invalid_argument
} catch (const invalid_argument& e) {
cout << "Invalid argument: " << e.what() << endl;
} catch (const out_of_range& e) {
cout << "Out of range: " << e.what() << endl;
}
// 数字转字符串
string s1 = to_string(123); // "123"
string s2 = to_string(3.14); // "3.140000"
string s3 = to_string(true); // "1"
大小写转换
string s = "Hello World";
// 转换为大写
transform(s.begin(), s.end(), s.begin(), ::toupper);
cout << s << endl; // "HELLO WORLD"
// 转换为小写
transform(s.begin(), s.end(), s.begin(), ::tolower);
cout << s << endl; // "hello world"
// 使用C++11的lambda
transform(s.begin(), s.end(), s.begin(),
[](unsigned char c) { return toupper(c); });
3.8 字符串分割和连接
分割字符串
vector<string> split_string(const string& str, char delimiter) {
vector<string> tokens;
string token;
istringstream token_stream(str);
while (getline(token_stream, token, delimiter)) {
if (!token.empty()) {
tokens.push_back(token);
}
}
return tokens;
}
// 使用示例
string data = "apple,banana,cherry,date";
vector<string> fruits = split_string(data, ',');
// fruits = {"apple", "banana", "cherry", "date"}
连接字符串
// 使用 + 运算符
string s1 = "Hello" + string(" ") + "World"; // "Hello World"
// 使用 append
string s2 = "Hello";
s2.append(" ").append("World"); // "Hello World"
// 连接字符串数组
vector<string> words = {"Hello", "World", "!"};
string result;
for (const auto& word : words) {
if (!result.empty()) result += " ";
result += word;
}
// result = "Hello World !"
// 使用 accumulate (C++17)
#include <numeric>
string joined = accumulate(next(words.begin()), words.end(), words[0],
[](string a, string b) { return a + " " + b; });
3.9 字符串算法操作
#include <algorithm>
string s = "Hello World";
// 反转字符串
reverse(s.begin(), s.end()); // "dlroW olleH"
reverse(s.begin(), s.end()); // 恢复原状
// 排序字符串
sort(s.begin(), s.end()); // " HWdellloor"
sort(s.begin(), s.end(), greater<char>()); // "roollledWH "
// 移除特定字符
s = "Hello World";
s.erase(remove(s.begin(), s.end(), 'l'), s.end());
// s = "Heo Word"
// 移除连续重复字符
s = "Hellooo Wooorld";
auto last = unique(s.begin(), s.end());
s.erase(last, s.end());
// s = "Helo World"