目录
[一、定义和初始化 string](#一、定义和初始化 string)
[二、string 常用迭代器](#二、string 常用迭代器)
[三、string 常用运算符](#三、string 常用运算符)
[四、string 常用成员函数](#四、string 常用成员函数)
[1.size 和 length 成员函数](#1.size 和 length 成员函数)
[2.find 成员函数](#2.find 成员函数)
[3.rfind 成员函数](#3.rfind 成员函数)
[4.find_first_of 成员函数](#4.find_first_of 成员函数)
[5.find_first_not_of 成员函数](#5.find_first_not_of 成员函数)
[6.find_last_of 成员函数](#6.find_last_of 成员函数)
[7.find_last_not_of 成员函数](#7.find_last_not_of 成员函数)
[8.empty 成员函数](#8.empty 成员函数)
[9.insert 成员函数](#9.insert 成员函数)
[10.erase 成员函数](#10.erase 成员函数)
[11.push_back 成员函数](#11.push_back 成员函数)
[12.pop_back 成员函数](#12.pop_back 成员函数)
[13.replace 成员函数](#13.replace 成员函数)
[14.substr 成员函数](#14.substr 成员函数)
[15.c_str 成员函数](#15.c_str 成员函数)
[五、用于 string 的全局函数](#五、用于 string 的全局函数)
[1.getline 函数](#1.getline 函数)
[2.stod 函数](#2.stod 函数)
[3.stoi 函数](#3.stoi 函数)
[4.stoull 函数](#4.stoull 函数)
[5.to_string 函数](#5.to_string 函数)
[六、基于范围 for 处理每个字符](#六、基于范围 for 处理每个字符)
前言
本文详细介绍了C++中string类的使用方法,主要包括:1. 多种初始化方式(空字符串、C风格字符串、重复字符等);2. 迭代器类型及遍历方法;3. 常用运算符重载(赋值、连接、比较等);4. 核心成员函数(查找、插入、删除、替换等);5. 全局函数(类型转换、输入输出等);6. 基于范围的for循环遍历。文章通过具体代码示例演示了string类的各种操作,包括字符串处理、查找替换、类型转换等功能,涵盖了string类的主要应用场景。
一、定义和初始化 string
在 C++ 中,string 是标准库中提供的字符串类,定义在 <string> 头文件中,位于 std 命名空间内。
cpp
#include <string>
using namespace std;
初始化方式:
-
默认初始化:创建一个空字符串
cppstring s1; // s1 是一个空字符串 -
使用 C 风格字符串初始化:
cppstring s2("Hello, World!"); // s2 初始化为 "Hello, World!" -
使用字符串字面值初始化:
cppstring s3 = "Hello, World!"; // 等同于上面的方式 -
使用另一个 string 对象初始化:
cppstring s4(s2); // s4 是 s2 的副本 string s5 = s2; // 同样是 s2 的副本 -
使用部分字符串初始化:
cppstring s6("Hello, World!", 5); // s6 初始化为 "Hello"(前 5 个字符) -
使用重复字符初始化:
cppstring s7(10, 'a'); // s7 初始化为 "aaaaaaaaaa"(10 个 'a') -
使用迭代器范围初始化:
cppstring s8(s2.begin(), s2.begin() + 5); // s8 初始化为 "Hello"
二、string 常用迭代器
string 类提供了多种迭代器类型,用于遍历字符串中的字符:
|-------------|-----------------------------|
| 迭代器 | 含义 |
| s.begin() | 第一个元素的迭代器 |
| s.end() | 最后一个元素的下一个位置迭代器(尾后迭代器或尾迭代器) |
| s.cbegin() | 第一个元素的常量迭代器(不修改元素内容) |
| s.cend() | 尾后常量迭代器(不修改元素内容) |
| s.rbegin() | 从后往前的第一个迭代器 |
| s.rend() | 从后往前的最后一个迭代器 |
| s.crbegin() | 从后往前的第一个常量迭代器 |
| s.crend() | 从后往前的最后一个常量迭代器 |
使用示例:
cpp
int main()
{
string s("abcde");
for (string::const_iterator i = s.cbegin(); i != s.cend(); i++)//输出每个字符并加,
cout << *i << ",";
cout << endl;
for (auto i2 = s.rbegin(); i2 != s.rend(); i2++)//逆序输出每个字符并加 空格
cout << *i2 << " ";
cout << endl;
for (auto i3 = s.begin()+2; i3 != s.end(); i3++)//把除前2个字符外的字母变成大写
*i3 = toupper(*i3); //需要引用cctype文件,在vs2022中可以不引用,因为string中已经引用过该文件
cout << s << endl;
return 0;
}
说明: toupper函数把小写字母转为大写字母,该函数是C语言函数,由于C++兼容C也可以直接使用,但需要引用对应的头文件cctype。
三、string 常用运算符
string 类重载了多种运算符,方便字符串操作:
|---------------|------------------------|
| 运算符 | 含义 |
| s1=s2 | 把s2的值赋值给s1 |
| s1+s2 | 返回s1和s2连接后的结果 |
| s1==s2 | 判断是否相等,区分大小写 |
| s1!=s2 | 判断是否不相等 |
| <,<=,>,>= | 判断大小关系,利用字典序进行比较,区分大小写 |
| s1+=s2 | 在s1的后面连接s2 |
| s1[i] | 返回s1第i个字符的引用,从0开始 |
| cout<<s | 输出s到输出流cout |
| cin>>s | 从cin输入流读取字符串到s |
使用示例:
cpp
int main() {
string s1("abcde");
string s2;
string s3;
s2 = s1; //把s1的内容复制给s2;
s3 = s1 + s2;//s1和s2的内容连结在一起复制给s3
cout << "s1:" << s1 << endl;
cout << "s2:" << s2 << endl;
cout << "s3:" << s3 << endl;
if (s1 == s2) //判断两个字符串的内容是否相等
cout << "s1==s2" << endl;
if (s1 != s2)//判断两个字符串的内容是否不相等
cout << "s1!=s2" << endl;
if (s1 < s3)//判断两个字符串的大小
cout << "s1<s3" << endl;
else if (s1 > s3)
cout << "s1>s3" << endl;
else
cout << "s1==s3" << endl;
s1 += s2; //把s2的值连结到s1的末尾
cout << "s1:" << s1 << endl;
cout << "s2:" << s2 << endl;
s1[0] = 'x'; //通过下标访问s1的内容
cout << "s1:" << s1 << endl;
return 0;
}
四、string 常用成员函数
|---------------------|-----------------|
| string s 的成员函数 | 含义 |
| s.empty() | 判断是否为空串 |
| s.size() | 返回s的字符个数 |
| s.length() | 返回s的字符个数 |
| s.find() | 查找字符或字符串 |
| s.rfind() | 从后往前查找 |
| s.find_first_of | 查找第一个在字符集中的字符 |
| s.find_first_not_of | 查找第一个不在字符集中的字符 |
| s.find_last_of | 查找最后一个在字符集中的字符 |
| s.find_last_not_of | 查找最后一个不在字符集中的字符 |
| s.insert() | 插入 |
| s.erase() | 删除字符或字符串 |
| s.push_back() | 尾插 |
| s.pop_back() | 尾删 |
| s.replace() | 替换 |
| s.substr() | 复制子串 |
| s.swap() | 字符串交换 |
| s.c_str() | string转换成c风格字符串 |
| s.at() | 获取指定位置的引用 |
1.size 和 length 成员函数
-
功能:返回字符串的长度(字符个数)
-
参数:无
-
返回值 :字符串的长度,类型为
size_t -
区别 :两者功能相同,
length()是为了与早期 C++ 兼容,size()是 STL 风格的命名
cpp
string s = "Hello";
cout << s.size(); // 输出: 5
cout << s.length(); // 输出: 5
2.find 成员函数
-
功能 :在字符串中查找子串或字符的第一次出现位置
-
参数:
-
str:要查找的子串 -
pos:开始查找的位置(默认为 0)
-
-
返回值 :找到的位置,若未找到则返回
string::npos
cpp
string s = "Hello, World!";
size_t pos = s.find("World");
if (pos != string::npos) {
cout << "Found at position: " << pos; // 输出: Found at position: 7
}
3.rfind 成员函数
-
功能 :在字符串中查找子串或字符的最后一次出现位置
-
参数:
-
str:要查找的子串 -
pos:开始查找的位置(默认为string::npos,表示从字符串末尾开始)
-
-
返回值 :找到的位置,若未找到则返回
string::npos
cpp
string s = "Hello, World!";
size_t pos = s.rfind("o");
if (pos != string::npos) {
cout << "Found at position: " << pos; // 输出: Found at position: 8
}
4.find_first_of 成员函数
-
功能 :在字符串中查找第一个属于指定字符集的字符
-
参数:
-
str:包含要查找的字符集的字符串 -
pos:开始查找的位置(默认为 0)
-
-
返回值 :找到的位置,若未找到则返回
string::npos
cpp
string s = "Hello, World!";
size_t pos = s.find_first_of("aeiou");
if (pos != string::npos) {
cout << "First vowel at position: " << pos; // 输出: First vowel at position: 1
}
5.find_first_not_of 成员函数
-
功能 :在字符串中查找第一个不属于指定字符集的字符
-
参数:
-
str:包含要排除的字符集的字符串 -
pos:开始查找的位置(默认为 0)
-
-
返回值 :找到的位置,若未找到则返回
string::npos
cpp
string s = "Hello, World!";
size_t pos = s.find_first_not_of("Helo");
if (pos != string::npos) {
cout << "First non-'Helo' character at position: " << pos; // 输出: First non-'Helo' character at position: 5
}
6.find_last_of 成员函数
-
功能 :在字符串中查找最后一个属于指定字符集的字符
-
参数:
-
str:包含要查找的字符集的字符串 -
pos:开始查找的位置(默认为string::npos,表示从字符串末尾开始)
-
-
返回值 :找到的位置,若未找到则返回
string::npos
cpp
string s = "Hello, World!";
size_t pos = s.find_last_of("aeiou");
if (pos != string::npos) {
cout << "Last vowel at position: " << pos; // 输出: Last vowel at position: 8
}
7.find_last_not_of 成员函数
-
功能 :在字符串中查找最后一个不属于指定字符集的字符
-
参数:
-
str:包含要排除的字符集的字符串 -
pos:开始查找的位置(默认为string::npos,表示从字符串末尾开始)
-
-
返回值 :找到的位置,若未找到则返回
string::npos
cpp
string s = "Hello, World!";
size_t pos = s.find_last_not_of("!");
if (pos != string::npos) {
cout << "Last non-'!' character at position: " << pos; // 输出: Last non-'!' character at position: 11
}
8.empty 成员函数
-
功能 :判断字符串是否为空
-
参数:无
-
返回值 :如果字符串为空返回
true,否则返回false
cpp
string s1;
string s2 = "Hello";
cout << s1.empty(); // 输出: 1 (true)
cout << s2.empty(); // 输出: 0 (false)
9.insert 成员函数
-
功能 :在指定位置插入字符串或字符
-
参数:
-
pos:插入位置 -
str:要插入的字符串
-
-
返回值:插入后的字符串引用
cpp
string s = "Hello World";
s.insert(5, ","); // s 现在是 "Hello, World"
10.erase 成员函数
-
功能:删除字符串中的部分字符
-
参数:
-
pos:开始删除的位置(默认为 0) -
len:要删除的字符数(默认为string::npos,表示删除到字符串末尾)
-
-
返回值:删除后的字符串引用
cpp
string s = "Hello, World!";
s.erase(5, 2); // s 现在是 "HelloWorld!"
11.push_back 成员函数
-
功能 :在字符串末尾添加一个字符
-
参数:
c:要添加的字符
-
返回值:无
cpp
string s = "Hello";
s.push_back('!'); // s 现在是 "Hello!"
12.pop_back 成员函数
-
功能 :删除字符串末尾的一个字符
-
参数:无
-
返回值:无
cpp
string s = "Hello!";
s.pop_back(); // s 现在是 "Hello"
13.replace 成员函数
-
功能:替换字符串中的部分字符
-
参数:
-
pos:开始替换的位置 -
len:要替换的字符数 -
str:替换的字符串
-
-
返回值:替换后的字符串引用
cpp
string s = "Hello, World!";
s.replace(7, 5, "C++"); // s 现在是 "Hello, C++!"
14.substr 成员函数
-
功能:返回字符串的子串
-
参数:
-
pos:子串的起始位置 -
len:子串的长度(默认为string::npos,表示到字符串末尾)
-
-
返回值:子串
cpp
string s = "Hello, World!";
string sub = s.substr(7, 5); // sub 是 "World"
15.swap 成员函数
-
功能:交换两个字符串的内容
-
参数:
str:要交换的另一个字符串
-
返回值:无
cpp
string s1 = "Hello";
string s2 = "World";
s1.swap(s2); // s1 现在是 "World",s2 现在是 "Hello"
15.c_str 成员函数
-
功能:返回一个指向 C 风格字符串的指针(以 null 结尾)
-
参数:无
-
返回值:指向 C 风格字符串的指针
cpp
string s = "Hello";
const char* cstr = s.c_str();
cout << cstr; // 输出: Hello
16.at 成员函数
-
功能 :访问指定位置的字符(进行边界检查)
-
参数:
pos:字符的位置
-
返回值:指定位置的字符的引用
-
异常 :如果位置超出范围,抛出
out_of_range异常
cpp
string s = "Hello";
char c = s.at(0); // c 是 'H'
try {
c = s.at(10); // 抛出 out_of_range 异常
} catch (const out_of_range& e) {
cout << "Exception: " << e.what();
}
五、用于 string 的全局函数
下面的函数都不是string的成员函数,而是用于string比较常用的全局函数。
|---------------|----------------------------|
| 全局函数 | 作用 |
| getline | 从输入流读取一行字符 |
| stod | 将字符序列转换为 double |
| stoi | 将字符序列转换为int |
| stoull | 将字符序列转换为unsigned long long |
| to_string | 把数字转成对应的字符串 |
1.getline 函数
-
功能:从输入流中读取一行字符串,直到遇到换行符
-
参数:
-
is:输入流对象 -
str:存储读取结果的字符串
-
-
返回值:输入流对象的引用
cpp
string s;
cout << "Enter a line: ";
getline(cin, s);
cout << "You entered: " << s;
2.stod 函数
-
功能:将字符串转换为 double 类型
-
参数:
-
str:要转换的字符串 -
idx:可选参数,用于存储转换后第一个未使用字符的位置
-
-
返回值:转换后的 double 值
cpp
string s = "3.14159";
double d = stod(s);
cout << d; // 输出: 3.14159
3.stoi 函数
-
功能:将字符串转换为 int 类型
-
参数:
-
str:要转换的字符串 -
idx:可选参数,用于存储转换后第一个未使用字符的位置 -
base:可选参数,转换的基数(默认为 10)
-
-
返回值:转换后的 int 值
cpp
string s = "123";
int i = stoi(s);
cout << i; // 输出: 123
4.stoull 函数
-
功能:将字符串转换为 unsigned long long 类型
-
参数:
-
str:要转换的字符串 -
idx:可选参数,用于存储转换后第一个未使用字符的位置 -
base:可选参数,转换的基数(默认为 10)
-
-
返回值:转换后的 unsigned long long 值
cpp
string s = "123456789012345";
unsigned long long ull = stoull(s);
cout << ull; // 输出: 123456789012345
5.to_string 函数
-
功能 :将数值转换为字符串
-
参数:
val:要转换的数值(可以是 int、long、long long、unsigned int、unsigned long、unsigned long long、float、double 或 long double)
-
返回值:转换后的字符串
cpp
int i = 123;
string s = to_string(i);
cout << s; // 输出: 123
六、基于范围 for 处理每个字符
C++11 引入了基于范围的 for 循环,可以更简洁地遍历字符串中的每个字符:
语法:
cpp
for (char c : str) {
// 处理字符 c
}
示例:
cpp
string s("hello");
//输出
for (auto x : s) //对于s中的每一个字符
cout << x << " ";//输出当前字符,后面紧跟一个空格
// 修改字符串中的字符
for (auto& c : s) //对于s中的每个字符(注意:c是引用)
c = toupper(c);//c是引用,因此赋值将改变s中字符的值
cout << s << endl;
注意事项:
-
如果只是读取字符,使用
auto c -
如果需要修改字符,使用
auto& c -
基于范围的 for 循环会自动遍历字符串中的每个字符,不需要手动管理索引或迭代器