C++ string 类完整学习指南

1. 基础概念与头文件

必需头文件

1
2
3
4
5
#include <string>      // string 类
#include <iostream> // 输入输出
#include <algorithm> // 算法操作(sort, reverse等)
#include <sstream> // 字符串流
#include <cctype> // 字符处理(toupper等)

基本声明与初始化

1
2
3
4
5
string s1;                    // 空字符串
string s2 = "Hello"; // 用C风格字符串初始化
string s3(s2); // 用另一个string初始化
string s4(5, 'A'); // 用多个相同字符初始化:"AAAAA"
string s5 = s2 + " World"; // 字符串连接

2. 输入输出操作

输入方法对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string str;

// 方法1:cin(遇到空格/换行停止)
cin >> str; // 读取单个单词

// 方法2:getline(读取整行)
getline(cin, str); // 读取整行,包括空格

// ⚠️ 重要:混合使用时的处理
int num;
string name;

cin >> num; // 读取数字
cin.ignore(); // 忽略换行符,避免影响后续getline
getline(cin, name); // 现在可以正确读取整行

输出方法

1
2
3
4
5
string str = "Hello World";

cout << str; // 标准输出
cout << str[0]; // 输出单个字符
printf("%s", str.c_str()); // 使用C风格输出(需要转换)

3. 字符串基本信息获取

长度与容量

1
2
3
4
5
6
string str = "Hello";

str.length(); // 返回字符串长度:5
str.size(); // 同length()
str.empty(); // 判断是否为空字符串
str.capacity(); // 返回当前分配的存储空间大小

字符访问

1
2
3
4
5
6
7
8
9
10
11
string str = "Hello";

// 使用下标访问
char c1 = str[0]; // 'H'

// 使用at()访问(边界检查,更安全)
char c2 = str.at(1); // 'e'

// 首尾字符访问
char first = str.front(); // 'H'
char last = str.back(); // 'o'

4. 字符串修改操作

追加与连接

1
2
3
4
5
string str = "Hello";

str.append(" World"); // "Hello World"
str += "!"; // "Hello World!"
str.push_back('?'); // "Hello World!?"

插入与删除

1
2
3
4
5
6
7
8
string str = "Hello World";

// 插入 => str.insert(位置, 字符串)
str.insert(5, " C++"); // "Hello C++ World"

// 删除 => str.erase(位置, 长度)
str.erase(5, 4); // 从位置5开始删除4个字符 → "Hello World"
str.clear(); // 清空字符串

替换操作

1
2
3
4
string str = "Hello World";

// replace替换 => str.replace(位置, 长度, 新字符串)
str.replace(6, 5, "C++"); // "Hello C++"

5. 字符串查找与子串

查找操作

1
2
3
4
5
6
7
8
9
10
11
12
string str = "Hello World";

// find查找 => str.find(字符串) 返回位置索引
size_t pos = str.find("World"); // 返回位置6
size_t notFound = str.find("Java"); // 返回 string::npos

// 检查查找结果
if (pos != string::npos) {
cout << "找到子串,位置:" << pos;
} else {
cout << "未找到子串";
}

子串提取

1
2
3
4
5
string str = "Hello World";

// substr提取 => str.substr(起始位置, 长度)
string sub1 = str.substr(6, 5); // "World"
string sub2 = str.substr(6); // "World"(从6到结尾)

6. 字符串比较与遍历

比较操作

1
2
3
4
5
6
7
8
string s1 = "apple";
string s2 = "banana";

if (s1 == s2) {
cout << "相等";
} else if (s1 < s2) {
cout << "s1 小于 s2"; // 字典序比较
}

遍历方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string str = "Hello";

// 方法1:下标遍历
for (int i = 0; i < str.length(); i++) {
cout << str[i];
}

// 方法2:基于范围循环(推荐)
for (char c : str) {
cout << c;
}

// 方法3:使用迭代器
for (auto it = str.begin(); it != str.end(); ++it) {
cout << *it;
}

7. 字符串与数值转换

1
2
3
4
5
6
7
8
// 数字转字符串
int num = 123;
string str1 = to_string(num); // "123"

// 字符串转数字
string str2 = "456";
int num2 = stoi(str2); // 456
double num3 = stod("3.14"); // 3.14

8. 常用算法操作

排序与反转

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <algorithm>

string str = "hello";

// reverse反转 => reverse(str.begin(), str.end())
reverse(str.begin(), str.end()); // "olleh"

// sort排序 => sort(str.begin(), str.end())
sort(str.begin(), str.end()); // "ehllo"(字典序)

// 对字符串数组排序
vector<string> words = {"dog", "cat", "ant"};
sort(words.begin(), words.end()); // {"ant", "cat", "dog"}

字符处理

1
2
3
4
5
6
7
8
9
10
11
12
#include <cctype>

char c = 'a';

// 大小写转换
char upper = toupper(c); // 'A'
char lower = tolower('B'); // 'b'

// 字符类型判断
isalpha(c); // 是否是字母
isdigit(c); // 是否是数字
isspace(c); // 是否是空白字符

9. 实际应用案例

案例1:字符串逆序

1
2
3
4
5
6
7
8
9
10
// 方法1:使用reverse函数
reverse(str.begin(), str.end());

// 方法2:手动交换字符
int left = 0, right = str.length() - 1;
while (left < right) {
swap(str[left], str[right]); // swap交换字符
left++;
right--;
}

案例2:统计字符出现次数和位置

1
2
3
4
5
6
7
8
9
10
11
string str = "hello world";
char target = 'l';
int count = 0, firstPos = -1;

for (int i = 0; i < str.length(); i++) {
if (str[i] == target) {
count++;
if (firstPos == -1) firstPos = i + 1;
}
}
cout << count << " " << firstPos; // 输出:3 3

案例3:判断回文字符串

1
2
3
4
5
6
7
8
bool isPalindrome = true;
for (int i = 0; i < str.length() / 2; i++) {
if (str[i] != str[str.length() - 1 - i]) {
isPalindrome = false;
break;
}
}
cout << (isPalindrome ? "Yes!" : "No!");

案例4:输出单词首字母大写

1
2
3
4
5
stringstream ss(str);
string word;
while (ss >> word) {
cout << (char)toupper(word[0]); // 输出每个单词首字母大写
}

案例5:寻找第一个不重复字符

1
2
3
4
5
6
7
8
9
10
int count[256] = {0};//ASCII范围 0~255
// 第一次遍历统计频率
for (char c : str) count[(unsigned char)c]++;//将c转化为unsigned char无符号类型,避免莫名奇妙的负值出现,~=count(c)++
// 第二次遍历找到第一个频率为1的字符
for (int i = 0; i < str.length(); i++) {
if (count[(unsigned char)str[i]] == 1) {//遍历查找只出现1次的字符
cout << str[i];
break;
}
}

10. String 特性速查表

分类 操作 语法 说明
基本信息 长度获取 str.length()str.size() 获取字符数量
空判断 str.empty() 是否为空字符串
字符访问 下标访问 str[i] 访问第i个字符
安全访问 str.at(i) 带边界检查的访问
首尾字符 str.front(), str.back() 第一个和最后一个字符
字符串修改 追加 str.append(s), str += s 字符串追加
插入 str.insert(pos, s) 在指定位置插入
删除 str.erase(pos, len) 删除子串
替换 str.replace(pos, len, s) 替换子串
清空 str.clear() 清空字符串
查找子串 查找 str.find(s) 查找子串位置
提取 str.substr(pos, len) 提取子串
算法操作 反转 reverse(str.begin(), str.end()) 反转字符串
排序 sort(str.begin(), str.end()) 字典序排序
交换 swap(str1, str2) 交换两个字符串
字符处理 大小写 toupper(c), tolower(c) 字符大小写转换
类型转换 转字符串 to_string(num) 数字转字符串
字符串转数字 stoi(str), stod(str) 字符串转数字

11. 重要注意事项

  1. getline 后的 cin.ignore

    1
    2
    3
    4
    5
    int age;
    string name;
    cin >> age;
    cin.ignore(); // 必须调用,清除缓冲区的换行符
    getline(cin, name);
  2. 字符串比较不要用 == 比较 C 风格字符串

    1
    2
    3
    string str = "hello";
    if (str == "hello") { ... } // 正确:比较内容
    if (str.c_str() == "hello") { ... } // 错误:比较地址
  3. 访问前检查边界

    1
    2
    3
    4
    5
    6
    7
    string str = "hi";
    // 使用 at() 会抛出异常
    try {
    char c = str.at(10); // 抛出 std::out_of_range
    } catch (const out_of_range& e) {
    cout << "索引越界";
    }
  4. 处理查找失败

    1
    2
    3
    4
    string str = "hello";
    if (str.find("world") == string::npos) {
    cout << "未找到";
    }
wow,你居然看完了,good job,欢迎联系我补充啊!!!