C++语言程序设计——06 字符串
目录
- 一、字符和字符串
- 二、字符串的相关操作
- (一)空字符串
- (二)访问索引
- (三)是否为空
- (四)获取长度
- (五)字符串拼接/添加
- (六)查找索引
- (七)提取子串
- (八)替换子串
- (九)删除子串
一、字符和字符串
结合之前学过的数据类型以及 ASCII 码,我们知道字符是用单引号包裹(''
),本质是 ASCII 码值的整数,并且只能有一个字符,数据类型用 char 表示。(包括转义字符,如 ‘\n’ 表示换行)。
#include <iostream>
using namespace std;
int main()
{char n1; // 定义了数据类型为字符类型的变量n1n1 = 'A';cout << n1-0 << endl; // -0会直接把该字符的 ASCII 码输出cout << "今天是2025年!!!Happy@@@"; // 字符串return 0;
}
运行结果如下:
而字符串不一样,是以双引号包裹(""
),可以包含多个字符(中文、英文、符号等)。在 C++ 中,字符串有专门的数据类型,即 string(需要包含头文件 < string >)。
二、字符串的相关操作
(一)空字符串
当声明字符串变量时如果不初始化,会自动创建一个空字符串(内部长度为 0,不包含任何字符),因为标准库会自动处理默认初始化。另外,如果我们想表示一个空字符串,直接定义就可以,不需要初始化:
#include <iostream>
#include <string> // 需要导入该头文件
using namespace std;
int main()
{string n1; // 直接定义就可以初始化string n2 = ""; // 这种也可以,不过没前面的简洁return 0;
}
(二)访问索引
访问字符串索引可以通过[ ]
或者at()
来实现,区别就是后者
会做越界检查,越界则会抛出 out_of_range 异常。
例如,下面代码通过for循环依次访问字符串索引,s.size() 获取字符串长度,s[i] 通过索引访问每个字符,同时循环变量 i 从0开始,每次递增1,直到字符串末尾:
#include <iostream>
#include <string>
using namespace std;
int main()
{string s = "12345";for (int i = 0; i < s.size(); i++) cout << s[i] << endl;return 0;
}
也可以对 for 循环进行简化:
for (char c : s) cout << c << endl;
代码如下:
#include <iostream>
#include <string>
using namespace std;
int main()
{string s = "12345";for (char c : s) cout << c << endl;return 0;
}
运行结果:
(三)是否为空
empty()
是string 类的成员函数,其作用是判断字符串是否为空,会返回一个布尔值(true或false),由于输出时会被自动转换为整数:true 对应 1,false 对应 0。
empty() 结果 | 描述 |
---|---|
1 | 字符串为空 |
0 | 字符串非空 |
#include <iostream>
#include <string> // 需要导入该头文件
using namespace std;
int main()
{string n1; // 直接定义就可以初始化string n2 = ""; // 这种也可以,不过没前面的简洁cout << n1.empty() << endl;cout << n2.empty() << endl;return 0;
}
运行结果如下,由于都是空的,所以都显示1:
empty( )是 string 类中的一个成员函数,这里 “.” 的意思是要对 n1 这个 string 类型的变量调用 empty() 函数,即用 n1 这个字符串的 empty() 功能来检查它是否为空。
(四)获取长度
首先,我们要知道字符串也是由很多个字符组成的。
这里我们通过 成员函数 size()
来返回 string 对象中存储的 “字符元素数量”(每个元素是 char 类型,占 1 个字节)。
在 C++ 中,字符串的编码取决于你的编译器 / 运行环境(Windows 下默认是 GBK 编码,Linux/macOS 下默认是
UTF-8 编码),不同编码下中文占的字节数不同:
➡️GBK 编码(Windows 常见):1 个中文汉字 / 中文符号占 2 个字节(即 2 个 char 元素)。
➡️UTF-8编码(Linux/macOS 常见):1 个中文汉字 / 中文符号占 3 个字节(即 3 个 char 元素)。
➡️英文、数字、英文符号(如2025、@、#):无论哪种编码,都占 1 个字节(1 个 char 元素)。
例如,下面代码中该字符串包含中文、英文、符号等:
#include <iostream>
#include <string> // 需要导入该头文件
using namespace std;
int main()
{string n1; string n2 = "今天是2025年,happy@#¥!";cout << n1.size() << endl;cout << n2.size() << endl;return 0;
}
运行结果如下:
n1 是空字符串,所以第一个输出显示为0。n2 字符串中, 正常的Windows电脑中,使用 GBK 编码(中文 / 中文符号占 2 字节),这里的¥是中文符号,所以:
总字节数 = 中文 (4×2) + 中文符号 (1×2) + 数字 (4×1) + 英文符号 (4×1) + 英文字母 (5×1)
= 8 + 2 + 4 + 4 + 5 = 23。
(五)字符串拼接/添加
1、加号拼接
直接用 +
连接多个字符串,会生成一个新的字符串,如下代码:
#include <iostream>
#include <string> // 需要导入该头文件
using namespace std;
int main()
{string n1 = "今天是"; string n2 = "2025年9月4日";cout << n1 + n2;return 0;
}
运行结果如下:
2、+= 直接拼接
也可以通过用 +=
追加,给已有的字符串的末尾添加内容(直接修改原字符串),如下代码:
#include <iostream>
#include <string> // 需要导入该头文件
using namespace std;
int main()
{string n1 = "今天是"; n1 += "2025年9月4日";n1 += "!";cout << n1;return 0;
}
运行结果如下:
3、append() 末尾添加
append()
函数可以在一个字符串的末尾追加整个字符串或者精确添加部分字符串,如下代码:
#include <iostream>
#include <string>
using namespace std;int main()
{string n1 = "今天是";n1.append("2025年9月4日");cout << n1;return 0;
}
运行结果如下:
也可以精确进行添加,如下代码,n1.append(n2, 0, 3) 表示从 n2 的第 0 个字符开始,截取 3 个字符,追加到 n1 后面:
#include <iostream>
#include <string>
using namespace std;int main()
{string n1 = "I love ";string n2 = "C++ !";n1.append(n2, 0, 3); //将 n2 中从索引 0 开始的 3 个字符拼接到 n1 的末尾cout << n1 ; return 0;
}
要注意 n2 中的字符依次是:‘C’、‘+’、‘+’、’ ‘(空格)、’!'(中文感叹号),运行结果如下:
4、insert() 插入
通过使用insert()
函数在字符串的指定位置插入另一个字符串(如果插入到末尾,就相当于拼接):
#include <iostream>
#include <string>
using namespace std;
int main()
{string n1 = "2025年9月4日";n1.insert(0, "今天是"); // 在位置0(字符串开头)插入"今天是"cout << n1; // 输出:今天是2025年9月4日return 0;
}
运行结果如下:
总结一下字符串拼接几种方法适合的地方:
名称 | 特点 |
---|---|
+= | 简便末尾拼接,能直接追加整串 |
append() | 可追加部分字符串 |
insert() | 可任意位置插入(含末尾) |
(六)查找索引
可以通过find()
来查找相应的字符在字符串中的索引位置(默认从0开始),例如下面代码中,就是查找字符串变量 s 中字母o的出现位置以及特定从索引6开始搜索:
#include <iostream>
#include <string>
using namespace std;int main()
{string s = "Hello World!";cout << s.find('o') << endl; // 查找"World"中字母o的索引,默认从 0 开始 cout << s.find('o',6); // 查找"World"中字母o的索引,从索引位置 6 开始 return 0;
}
运行结果如下:
➡️find()还有几种类似的用法:
rfind():从字符串末尾开始查找(最后一次出现的位置)。
find_first_of():查找任何一个匹配字符的第一个位置。
find_last_of():查找任何一个匹配字符的最后一个位置。
(七)提取子串
substr()
用于提取子字符串,可提取指定位置和长度的子字符串。
#include <iostream>
#include <string>
using namespace std;int main()
{string s = "Hello World!";cout << s.substr(6) << endl; // 从索引6开始提取到末尾 → 得到"World!"cout << s.substr(0, 5); // 从索引0开始提取5个字符 → 得到"Hello"return 0;
}
运行结果如下:
(八)替换子串
replace()
可以替换字符串中指定位置或范围的字符。另外,要注意,当指定的替换长度超过字符串剩余长度时,replace() 会替换从起始位置到字符串末尾的所有内容。例如,字符串变量s = “Hello World!”,其长度为 12(索引范围 0~11),从字符串 s 的索引 6 开始,替换长度为 11 的字符为 “C++”:
#include <iostream>
#include <string>
using namespace std;int main()
{string s = "Hello World!";cout << s.replace(6,11,"C++") << endl; // 从字符串 s 的索引 6 开始,替换长度为 11 的字符为 "C++"return 0;
}
运行结果如下:
(九)删除子串
可以通过erase()
来删除子字符串,即删除字符串中指定位置或范围的字符。例如,字符串变量s = “Hello World!”,其长度为 12(索引范围 0~11)。
#include <iostream>
#include <string>
using namespace std;int main()
{string s = "Hello World!";cout << s.erase(6,11) << endl; // 从字符串 s 的索引 6 开始,删除长度为 11 的字符。return 0;
}
这里是从索引 6 开始删除,删除 11 个字符,但从索引 6 到字符串末尾实际只有 6 个字符(“World!”)。