前言
string
是 C++ STL 中封装字符串的类,提供了丰富的接口用于字符串的创建、访问、拼接、修改、查找等操作。相比 C 风格字符串(char*
),string
自动管理内存,更安全、更方便。
本文基于个人练习代码整理,将零散的测试函数按功能重命名并加上详细注释,方便回顾。
1. 字符串的创建与初始化
功能说明
学习如何创建和初始化 string
对象,包括:
- 直接初始化
- 拷贝初始化
- 用 C 风格字符串初始化
- 用重复字符初始化
代码示例(含详细注释)
cpp
// 字符串的创建与初始化
void string_creation_and_initialization() {
string s1 = "唐三"; // 直接初始化
cout << "s1: " << s1 << endl;
string s2(s1); // 拷贝构造
cout << "s2: " << s2 << endl;
string s3 = s1; // 赋值初始化
cout << "s3: " << s3 << endl;
string s4("hello"); // 用C风格字符串初始化
cout << "s4: " << s4 << endl;
string s5 = "hello"; // 用C风格字符串直接赋值
cout << "s5: " << s5 << endl;
string s6(3, 'a'); // 用3个字符 'a' 初始化
cout << "s6: " << s6 << endl;
string s7 = string("world"); // 显式构造
cout << "s7: " << s7 << endl;
string s8(string("唐三")); // 拷贝构造(显式写法)
cout << "s8: " << s8 << endl;
}
初始化方式总结
初始化方式 | 示例 | 说明 |
---|---|---|
直接初始化 | string s = "abc"; |
使用 = 直接赋值字符串字面量 |
拷贝构造 | string s2(s1); |
使用另一个 string 初始化 |
C 风格字符串构造 | string s("abc"); |
用 const char* 初始化 |
重复字符构造 | string s(5, 'a'); |
创建由 5 个 'a' 组成的字符串 |
2. 字符串输入方式
功能说明
学习两种常见的字符串输入方法:
cin >> s;
:遇到空格或换行停止getline(cin, s);
:可以读取一整行(包括空格)
代码示例
cpp
// 用 cin 读取字符串(不含空格)
void string_input_with_cin() {
string s1;
cout << "请输入字符串(cin,空格结束):";
cin >> s1;
cout << "你输入的是:" << s1 << endl;
}
// 用 getline 读取整行(含空格)
void string_input_with_getline() {
string s1;
cout << "请输入字符串(getline,可含空格):";
getline(cin, s1);
cout << "你输入的是:" << s1 << endl;
}
注意事项
cin >> s;
适合读取单个单词getline(cin, s);
适合读取整行文本- 如果
getline
前有cin >> var;
,需要处理换行符:cin.ignore()
3. 字符串比较
功能说明
string
重载了比较运算符(==
, !=
, <
, <=
, >
, >=
),按字典序(ASCII 码)比较。
代码示例
cpp
void string_comparison() {
string s1 = "abc";
string s2 = "edf";
if (s1 < s2) {
cout << "s1 < s2" << endl;
} else {
cout << "s1 >= s2" << endl;
}
}
比较规则
- 按字符依次比较 ASCII 码值
- 如果一个是另一个的前缀,短的更小(如
"app"
<"apple"
)
4. 字符串连接
功能说明
- 使用
+
运算符拼接 - 使用
+=
运算符追加
代码示例
cpp
运行
void string_concatenation() {
string s1 = "123456", s2 = "abcdef", s3;
s3 = s1 + s2; // 拼接两个字符串
cout << "s1 + s2 = " << s3 << endl;
s1 += s2; // 追加到末尾
cout << "s1 += s2 = " << s1 << endl;
// 注意:两个字符串字面量不能直接相加
// string s4 = "xiaoming" + "china"; // ❌ 编译错误
string s4 = string("xiaoming") + "china"; // ✅ 正确
cout << s4 << endl;
}
5. 字符串遍历
功能说明
常见遍历方式:
- 下标
[]
- 范围 for 循环(C++11)
- 迭代器
代码示例
cpp
void string_traversal() {
string s = "abcdefghijk";
// 1. 范围 for(C++11)
cout << "范围 for 遍历: ";
for (auto c : s) {
cout << c << " ";
}
cout << endl;
// 2. 下标访问
cout << "下标访问遍历: ";
for (int i = 0; i < s.size(); i++) {
cout << s[i] << " ";
}
cout << endl;
// 3. 迭代器
cout << "迭代器遍历: ";
for (auto it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
6. 子串操作(substr)
功能说明
substr(pos, len)
:从位置 pos
开始截取长度为 len
的子串。
代码示例
cpp
void string_substr() {
string s = "value";
string s1 = s.substr(); // 截取全部
cout << "s1: " << s1 << endl;
string s2 = s.substr(3); // 从下标3到末尾
cout << "s2: " << s2 << endl;
string s3 = s.substr(s.size()); // 从末尾开始(空字符串)
cout << "s3: " << s3 << endl;
string s5 = s.substr(2, 3); // 从下标2开始,长度3
cout << "s5: " << s5 << endl;
string s7 = s.substr(3, 10); // 长度超出范围则到末尾
cout << "s7: " << s7 << endl;
}
7. 插入操作(insert)
功能说明
insert
可以在指定位置插入字符、字符串或区间。
代码示例
cpp
void string_insert() {
string s1 = "value";
s1.insert(s1.begin(), 's'); // 在开头插入 's'
cout << s1 << endl; // svalue
s1.insert(s1.begin(), 3, 'a'); // 在开头插入 3 个 'a'
cout << s1 << endl; // aaasvalue
s1.insert(s1.begin(), s1.begin(), s1.begin() + 2); // 插入一段区间
cout << s1 << endl;
s1.insert(s1.end(), {'e', 'f'}); // 插入初始化列表
cout << s1 << endl;
}
8. 删除操作(erase)
功能说明
erase
可以删除指定位置、区间或整个字符串。
代码示例
cpp
void string_erase() {
string s1 = "value";
s1.erase(); // 清空字符串
cout << "s1: " << s1 << endl;
string s2 = "value";
s2.erase(1, 3); // 从下标1开始删除3个字符
cout << "s2: " << s2 << endl; // ve
string s3 = "value";
s3.erase(s3.begin() + 1); // 删除迭代器位置字符
cout << "s3: " << s3 << endl; // vlue
string s4 = "value";
s4.erase(s4.begin(), s4.begin() + 2); // 删除区间
cout << "s4: " << s4 << endl; // lue
}
9. 替换操作(replace)
功能说明
replace(pos, len, ...)
:从位置 pos
开始,替换长度为 len
的部分。
代码示例
cpp
void string_replace() {
string s = "I very love China";
const char* cp1 = "truly";
const char* cp2 = "truly!!!!!";
string str1 = "really";
string str2 = "really!";
s.replace(2, 4, cp1); // 从下标2开始,替换4个字符为 "truly"
cout << s << endl;
s.replace(2, 5, cp1);
cout << s << endl;
s.replace(2, 5, str1);
cout << s << endl;
s.replace(2, 6, str2, 0, 6); // 替换为 str2 的子串
cout << s << endl;
s.replace(2, 6, 3, '*'); // 替换为 3 个 '*'
cout << s << endl;
}
10. 追加操作(append)
功能说明
append
用于在字符串末尾追加内容。
代码示例
cpp
void string_append() {
string s1 = "C++";
s1.append(" program"); // 追加字符串
cout << s1 << endl; // C++ program
}
11. 实战:删除字符串中的标点符号
功能说明
使用 ispunct()
判断标点符号,并过滤掉。
代码示例
cpp
#include <cctype> // ispunct 函数需要
void string_remove_punctuation() {
cout << "请输入字符串:";
string s;
getline(cin, s);
for (auto c : s) {
if (!ispunct(c)) { // 如果不是标点符号则输出
cout << c;
}
}
cout << endl;
}
12. string 常用操作速查表
操作 | 方法 | 示例 |
---|---|---|
长度 | size() / length() |
s.size() |
判空 | empty() |
if (s.empty()) |
访问 | [] / at() |
s[0] , s.at(0) |
拼接 | + / += / append() |
s + "abc" , s.append("xyz") |
子串 | substr(pos, len) |
s.substr(2, 3) |
插入 | insert(pos, ...) |
s.insert(2, "abc") |
删除 | erase(pos, len) / erase(it) |
s.erase(1, 2) |
替换 | replace(pos, len, ...) |
s.replace(1, 2, "xx") |
查找 | find() / rfind() |
s.find("abc") |
比较 | == , != , < , <= , > , >= |
s1 < s2 |
输入 | cin >> s / getline(cin, s) |
- |
输出 | cout << s |
- |
✅ 总结:
string
是可变长度的字符序列,自动管理内存- 支持丰富的操作:增删改查、比较、拼接、子串等
- 遍历方式多样:下标、范围 for、迭代器
- 注意
getline
和cin
的区别,以及ispunct
等字符判断函数的使用
C++ string 成员函数思维导图

最后附上我自己练习时的源码资料(有兴趣的可以按自己喜好自由练习修改):
头文件:
cpp
#pragma once
#include <string>
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
/*
声明函数方法
*/
//隔开函数
void gekai();
void test01();
void test02();
void test03();
void test04();
void test05();
void test06();
void test07();
void test08();
void test09();
//erase()删除函数使用
void test10();
//append()方法
void test11();
//
void test12();
//输入一串带有标点符号的字符串,去除字符串中的标点符号!
void judgmentPunctuation();
源文件:
cpp
#include "string.h"
/*
实现函数方法
*/
void judgmentPunctuation() {
//string s;
//cin >> s;
//int flag = 0;
////开始判断
////for (auto i = s.begin(); i != s.end(); i++) {
////}
//for (int i = 0; i < s.size(); i++) {
// if ((bool)ispunct(s[i])) {
// flag = i;
// s.erase(flag);
// }
//}
//cout << s << endl;
//方法二
cout << "请输入字符串:";
string s;
getline(cin, s);
for (auto c : s) {
if (!ispunct(c)) {
cout << c;
}
}
}
void test12() {
string s = "I very love China";
const char* cp1 = "truly";
const char* cp2 = "truly!!!!!";
string str1 = "really";
string str2 = "really!";
s.replace(2, 4, cp1);
cout << s << endl;
s.replace(2, 5, cp1);
cout << s << endl;
s.replace(2, 5, str1);
cout << s << endl;
s.replace(2, 6, str2,0,6);
cout << s << endl;
s.replace(2, 6, 3, '*');
cout << s << endl;
}
void test11() {
string s1 = "C++";
s1.append(" program");
cout << s1 << endl;
}
void test10() {
string s1 = "value";
string s2 = "value";
string s3 = "value";
string s4 = "value";
s1.erase();
cout << "s1" << s1 << endl;
s2.erase(1, 3);//ve
cout <<"s2" << s2 << endl;
s3.erase(s3.begin() + 1);//vlue
cout << "s3" << s3 << endl;
s4.erase(s4.begin(), s4.begin() + 2);//lue
cout << "s4" << s4 << endl;
}
void test09() {
string s1 = "value";
s1.insert(s1.begin(), 's');
cout << s1 << endl;//svalue
s1.insert(s1.begin(), 3, 'a');
cout << s1 << endl;//aaasvalue
s1.insert(s1.begin(), s1.begin(), s1.begin()+2);
cout << s1 << endl;
s1.insert(s1.end(), { 'e','f' });
cout << s1 << endl;
}
//取子串函数测试函数
void test08() {
string s = "value";
string s1 = s.substr();
cout << "s1:" << s1 << endl;
string s2 = s.substr(3);//ue
cout << "s2:" << s2 << endl;
//gekai();
string s3 = s.substr(s.size());
cout << "s3:" << s3 << endl;
//string s4 = s.substr(10);
//cout << s4 << endl;
string s5 = s.substr(2, 3);//lue
cout << "s5:" << s5 << endl;
//string s6 = s.substr(6, 2);
//cout << s6 << endl;
string s7 = s.substr(3, 10);//ue
cout << "s7:" << s7 << endl;
string s8 = s.substr(5, 10);
cout << "s8:" << s8 << endl;
}
void test07() {
string s1 = "hello";
string s2(s1, 1);
cout << s2 << endl;//ello
try {
string s3(s1, 8);
cout << s3 << endl;
}
catch (exception e) {
//e.what();
cout << "出错了!!!赶快改bug!!!" << endl;
}
string s4(s1, 5);
cout << s4 << endl;
string s5(s1, 0, 3);//hel
cout << s5 << endl;
string s6(s1, 2, 100);//ll0
cout << s6 << endl;
string s7(s1, 5, 3);//空字符
cout << s7 << endl;
try {
string s8(s1, 6, 2);
cout << s8 << endl;;
}
catch (exception e) {
//e.what();
cout << "出错了!!!赶快改bug!!!" << endl;
}
}
void test06() {
string s1 = "abcdefghijk";
//C++ 11 新特性
for (auto c : s1) {
cout << c << " ";
}
cout << endl;
cout << s1[0] << endl;
cout << s1 << endl;
for (int i = 0; i < s1.size(); i++) {
cout << s1[i] << " ";
}
cout << endl;
//使用迭代器(本质是指针)
for (auto i = s1.begin(); i != s1.end(); i++) {
cout << *i << " ";
}
gekai();
string s8(s1, 100);
cout << s8 << endl;
}
//字符串连接
void test05() {
string s1 = "123456", s2 = "abcdef", s3;
s3 = s1 + s2;
cout << s3 << endl;
//bug代码 const只读常量不能修改
//string s4 = "xiaoming" + "china";
//cout << s4 << endl;
}
void test04() {
string s1 = "abc";
string s2 = "edf";
//字符串比较大小实用的是ASCll码比较
if (s1 < s2) {
cout << "s1<s2" << endl;
}
else {
cout << "s1>s2" << endl;
}
}
void test03() {
string s1;
getline(cin, s1); //可以接收带空格的字符串
cout << s1 << endl;
}
void test02() {
string s1;
cin >> s1;//不可以接收带空格的字符串,遇到空格就会终止接收字符
cout << s1 << endl;
}
void test01() {
string s1="唐三";
cout << s1 << endl;
string s2(s1);
cout << s2 << endl;
string s3 = s1;
cout << s3 << endl;
string s4("hello");
cout << s4 << endl;
string s5 = "hello";
cout << s5 << endl;
string s6(3, 'a');
cout << s6 << endl;
string s7 = string("world");
cout << s7 << endl;
string s8(string("唐三"));
cout << s8 << endl;
}
void gekai() {
cout << endl << "######################################" << endl;
}