标准库类型 string
标准库类型 string 表示可变长的字符序列,使用 string 类型必须首先包含<string>
头文件。
定义和初始化 string 对象
默认初始化
string str; //默认初始化,str 是一个空串
拷贝初始化
如果使用等号=
初始化一个变量,实际上执行的是拷贝初始化。
string str = "Hello World";//拷贝初始化
直接初始化
如果不使用等号=
初始化一个变量,实际上执行的是直接初始化。
string str{ "Hello World" };//直接初始化
提供 string 大小,并指定显示的初始值
string str(5, 'A'); // 内含 5 个字符,这些字符的值为 A
将一个新 string 创建为另一个 string 的拷贝
string str1{ "C++" };
string str2{ str1 }; //对象的拷贝
string 对象上的操作
字符串的输入\输出
string str;
cin >> str;
cout << str << endl;
判断字符串是否为空
成员函数 empty 当 string 对象为空时返回 ture,否则返回 false。
string str;
cout << str.empty() << endl; //字符串为空,输出 1
获取字符串的长度
成员函数 size 返回 string 对象中的字符个数;返回类型为 size_type。
string str{ "Hello World" };
cout << str.size() << endl; //字符串长度为 11
为 string 对象赋值
string str1{ "Hello World" };
string str2{ "Hiya" };
str1 = str2;
cout << str1 << endl; //输出 Hiya
比较 string 对象
- 如果两个 string 对象相等,则它们的长度相同,而且它们所包含的字符也全都相同。
- 如果两个 string 对象的长度不同,但是较短的 string 对象的每个字符都与较长 string 对象对应位置上的字符相同,则较短的 string 对象小于较长的 string 对象。
- 如果两个 string 对象在某些对应的位置上不一致,则 string 对象比较的结果为它们中第一对相异字符的比较结果。
string str1{ "Hello" };
string str2{ "Hello World" };
string str3{ "Hiya" };
string str4{ str1 };
cout << (str1 < str2) << endl; // str1的长度小于str2的长度,输出 1
cout << (str1 < str3) << endl; // e < i,输出 1
cout << (str1 == str4) << endl; // str1等于str4,输出 1
两个 stirng 对象相加
两个 stirng 对象相加会得到一个新的 string 对象,其内容是把左侧的运算对象与右侧的运算对象串接而成。
string str1{ "Hello" };
string str2{ "World" };
string str3 = str1 + str2;
cout << str3 << endl; //输出 HelloWorld
str1 += str2; //等价于 str1 = str1 + str2
cout << str1 << endl; //输出 HelloWorld
字面值和 string 对象相加
string str1{ "Hello" };
string str2{ str1 + "," + "World" };
cout << str2 << endl; //输出 Hello,World
两个字符串字面值不能直接相加。
string str1{ "World" };
string str2{ "Hello" + "," + str1 }; //错误
处理 string 对象中的字符
<cctype>
头文件中主要的的函数:
共有函数 | 功能 |
---|---|
isalnum( c ) | 当 c 是字母或数字时为真 |
isalpha( c ) | 当 c 是字母时为真 |
iscntrl( c ) | 当 c 是控制字符时为真 |
isdigit( c ) | 当 c 是数字时为真 |
isgraph( c ) | 当 c 不是空格但可打印时为真 |
isprint( c ) | 当 c 是可打印时为真 |
isspace( c ) | 当 c 是空白时为真(即 c 是空格、横向制表符、纵向制表符、回车符、换行符、进纸符的一种) |
ispunct( c ) | 当 c 是标点符号时为真(即 c 不是控制字符、数字、字母、可打印空白中的一种) |
islower( c ) | 当 c 是小写字母时为真 |
isupper( c ) | 当 c 是大写字母时为真 |
isxdigit( c ) | 当 c 是十六进制数字时为真 |
tolower( c ) | 大写字母转小写字母 |
toupper( c ) | 小写字母转大写字母 |
遍历 string 对象中的字符
string str{ "Hello World" };
for (auto c : str )
{
cout << c;
}
cout << endl;
修改 string 对象中的每个字符
string str{ "Hello World" };
for (auto& c : str) //获取字符的引用
{
c = toupper(c); //小写字母转换成大写字母
}
cout << str << endl;
额外的 string 操作
构造 string 的其他方法
这些构造函数接受一个 string 对象或是一个const char*
参数,还接受(可选的)指定拷贝多少个字符的参数。
从字符指针指向的字符开始,拷贝 n 个字符。
char arrs[] = "HelloWorld"; //以空字符结尾的字符数组
string str1( arrs,5 ); //拷贝从 arrs[0] 到 arrs[4] 的 5 个字符
cout << str1 << endl; // str1 = Hello
string str2( arrs + 5, 5 ); //拷贝从 arrs[5] 到 arrs[9] 的 5 个字符
cout << str2 << endl; // str2 = World
当我们传递的是一个 string 对象时,可以给定一个下标来指出从哪里开始拷贝。
string s{ "HelloWorld" };
string str1( s,5 ); // 从 s[5] 开始,拷贝剩下的所有字符
cout << str1 << endl; // str1 = World
string str2( s,0,5 ); //拷贝从 s[0] 到 s[4] 的 5 个字符
cout << str2 << endl; // str2 = Hello
子字符串操作
成员函数 substr 返回一个 string 对象,它是原始 string 对象的一部分或全部的拷贝。
可以传递给 substr 一个可选的开始位置和计数值:
string s{ "Hello word" };
string str1{ s.substr(5) }; // 从 s[5] 开始,拷贝剩下的所有字符
cout << str1 << endl; // str1 = World
string str2{ s.substr(5, 1) }; // 从 s[5] 开始,拷贝 1 个字符
cout << str2 << endl; // str1 = W
如果开始位置超出了 string 的大小,则 substr 函数会抛出一个 out_of_range 异常。
如果开始位置加上计数值大于 string 的大小,则 substr 会调整计数值,只拷贝到 string 的末尾。
改变 string 的其他方法
string 类型支持顺序容器的赋值运算符以及 assign、insert 和 erase 操作。
除了接受迭代器的 assign、insert 和 erase 版本外,string 还提供了接受下标的版本。
assign 函数
替换一个字符串字面值。
string str{ "C++" };
str.assign( "World" );
cout << str << endl; //输出 World
替换一个以空字符结尾的字符数组。
string str{ "C++" };
char arrs[] = { "HelloWorld" };
str.assign( arrs );
cout << str << endl; //输出 HelloWorld
替换一个以空字符结尾的字符数组的子串(从字符指针指向的字符开始的 n 个字符)。
string str{ "C++" };
char arrs[] = { "HelloWorld" };
str.assign( arrs,5 ); //替换从 arrs[0] 到 arrs[4] 的 5 个字符
cout << str << endl; //输出 Hello
str.assign( arrs + 5, 4 );//替换从 arrs[5] 到 arrs[8] 的 4 个字符
cout << str << endl; //输出 Worl
替换另一个 string 对象。
string str1{ "C++" };
string str2{ "HelloWorld" };
str1.assign( str2 );
cout << str1 << endl; //输出 HelloWorld
替换另一个 string 对象的子串(从下标开始,剩下的所有字符)。
string str1{ "C++" };
string str2{ "HelloWorld" };
str1.assign( str2, 5 ); //替换从 str2[5] 到 str2[9] 的 5 个字符
cout << str1 << endl; //输出 World
str1.assign(str2, 0, 5); //替换从 str2[0] 到 str2[4] 的 5 个字符
cout << str1 << endl; //输出 Hello
替换 n 个相同的字符。
string str{ "C++" };
str.assign( 3,'A' );
cout << str << endl; //输出 AAA
替换一个花括号包围的字符列表。
string str{ "C++" };
str.assign({ 'A','B','C','D' });
cout << str << endl; //输出 ABCD
向 string 指定位置插入字符串
在下标指向的元素之前插入一个字符串字面值。
string str{ "Hello World" };
str.insert( 0, "A" ); //在 H 之前插入一个 A
cout << str << endl; //输出 AHello World
在下标指向的元素之前插入一个以空字符结尾的字符数组。
string str{ "Hello World" };
char arrs[] = { "C++" };
str.insert( 0,arrs ); //在 H 之前插入 C++
cout << str << endl; //输出 C++Hello World
在下标指向的元素之前插入一个以空字符结尾的字符数组的子串(从字符指针指向的字符开始的 n 个字符)。
string str{ "Hello World" };
char arrs[] = { "C++Java" };
str.insert( 0,arrs + 3,6 ); //在 H 之前插入 Java
cout << str << endl; //输出 JavaHello World
在下标指向的元素之前插入一个 string 对象。
string str1{ "Hello World" };
string str2{ "ABC" };
str1.insert( 0, str2 ); //在 H 之前插入 ABC
cout << str1 << endl; //输出 ABCHello World
在下标指向的元素之前插入一个另一个 string 对象的子串(从下标开始,剩下的所有字符)。
string str1{ "Hello World" };
string str2{ "C++Java" };
str1.insert(0, str2, 3); //在 H 之前插入 Java
cout << str1 << endl; //输出 JavaHello World
str1.insert(0, str2, 0, 1); //在 J 之前插入 C
cout << str1 << endl; //输出 CJavaHello World
在下标指向的元素之前插入 n 个相同的字符。
string str{ "Hello World" };
str.insert( str.size(), 3, '!'); //在 str 的末尾插入 3 个感叹号
cout << str << endl; //输出 Hello World!!!
在下标指向的元素之前插入一个花括号包围的字符列表。
string str{ "Hello World" };
str.insert(4, {'A','B','C'} ); //在 o 之前插入 ABC
cout << str << endl; //输出 HellABCo World
从 string 删除字符
删除从下标开始的剩下的所有字符。
string str{ "Helloword" };
str.erase( 5 ); //删除 world
cout << str << endl; //输出 Hello
删除从下标开始的 n 个字符。
string str{ "Helloword" };
str.erase( 5,1 ); //删除 w
cout << str << endl; //输出 Helloorld
append 和 replace 成员
string 类定义了两个额外的成员函数:append 和 replace。
成员函数 append 是在 string 对象的末尾插入字符串的一种简写形式。
string str{ "HelloWorld" };
str.append("C++"); //在末尾添加 C++
cout << str << endl; //输出 HelloWorldC++
等价形式:
string str{ "HelloWorld" };
str.insert(str.size(), "C++"); //在末尾添加 C++
cout << str << endl; //输出 HelloWorldC++
成员函数 replace 是调用 erase 和 insert 的一种简写形式。
string str{ "HelloWorld" };
str.replace( 0,5,"C++" ); //删除从 str[0] 到 str[4] 的 5 个字符,并替换为 C++
cout << str << endl; //输出 C++World
等价形式:
string str{ "HelloWorld" };
str.erase( 0,5 ); //删除从 str[0] 到 str[4] 的 5 个字符
str.insert( 0,"C++"); //在 str[0] 之前插入 C++
cout << str << endl;
string 搜索操作
string 类提供了 6 个不同的搜索函数,每个函数都有4个重载版本。
每个搜索操作都范回一个string::size_type
值,表示匹配发生位置的下标。
如果搜素失败,则返回一个名为string::npos
的 static 成员。
标准库将string::npos
定义为一个const string::size_type
类型,初始化值为 -1。
函数 | 功能 |
---|---|
find (str) | 查找 string 对象中 str 第一次出现的位置 |
rfind (str) | 查找 string 对象中 str 最后一次出现的位置 |
find_first_of (str) | 在 string 对象中查找 str 中任何一个字符第一次出现的位置 |
find_last_of (str) | 在 string 对象中查找 str 中任何一个字符最后一次出现的位置 |
find_first_not_of (str) | 在 string 对象中查找第一个不在 str 中的字符 |
find_last_not_of (str) | 在 string 对象中查找最后一个不在 str 中的字符 |
查找一个字符
string str{ "HelloWorld" };
cout << str.find('W') << endl; //输出 5
查找一个 string 对象
string str1{ "HelloWorld" };
string str2{ "World" };
cout << str1.find( str2 ) << endl; //输出 5
查找一个字符指针指向的字符数组(以空字符结尾)。
string str{ "HelloWorld" };
const char* arrs = "C++World";
cout << str.find( arrs + 3 ) << endl; //输出 5
cout << str.find("World") << endl; //输出 5
可以传递给 find 操作一个可选的开始位置;这个可选的参数指出从哪个位置开始搜索。
默认情况下,此位置被置为 0,即从头开始搜索。
/*查找'o'存在的所有位置*/
string str{ "HelloWorld" };
string::size_type i = 0;
while ( ( i = str.find('o', i) ) != string::npos )
{
cout << i << ' ';
++i;
}
copmare 函数
除关系运算符外,标准库 string 类型还提供了一组 compare 成员函数。
功能:将两个字符串自左至右逐个字符相比,直到出现不同的字符或遇到“\0
”为止。
- 字符串1 = 字符串2,返回值 = 0;
- 字符串1 < 字符串2,返回值 < 0;
- 字符串1 > 字符串2,返回值 > 0。
比较两个 string 对象
string str1{ "HelloWorld" };
string str2{ "HelloWorld" }; //以空字符结尾的字符数组
cout << str1.compare(str2) << endl; // str1 == str2 输出 0
将 str1 中从下标开始的 n 个字符与 str2 进行比较。
string str1{ "HelloWorld" };
string str2{ "Hello" };
cout << str1.compare( 0,5, str2) << endl; //比较 Hello,输出 0
将 str1 中从下标开始的 n 个字符与 str2 中从下标开始的 n 个字符进行比较。
string str1{ "HelloWorld" };
string str2{ "C++Hello" };
cout << str1.compare( 0,5, str2,3,5 ) << endl; //比较 Hello,输出 0
string 对象与字符指针指向的字符数组比较
string str{ "HelloWorld" };
char arrs[] = { "HelloWorld" };
cout << str.compare( arrs ) << endl; // str1 == str2 输出 0
将 str 中从下标开始的 n 个字符与字符指针指向的字符数组进行比较。
string str{ "HelloWorld" };
char arrs[] = { "C++World" };
cout << str.compare(5, 5, arrs +3 ) << endl; //比较 World,输出 0
将 str 中从下标开始的 n 个字符与字符指针指向的字符开始的 n 个字符进行比较。
string str{ "HelloWorld" };
char arrs[] = { "C++Hello" };
cout << str.compare(0,5,arrs + 3,5 ) << endl; //比较 Hello,输出 0
数值转换
新标准引入了多个函数,可以实现数值数据与标准库 string 之间的转换,它们都定义在<string>
头文件中。
函数 | 功能 |
---|---|
to_string (val) | 转换整数或浮点值为 string |
stoi (s,p,b) | 转换字符串为 int |
stol (s,p,b) | 转换字符串为 long |
stoul (s,p,b) | 转换字符串为 unsigned long |
stoll (s,p,b) | 转换字符串为 long long |
stoull (s,p,b) | 转换字符串为 unsigned long long |
stof (s,p) | 转换字符串为 float |
stod (s,p) | 转换字符串为 double |
stold (s,p) | 转换字符串为 long double |
将一个任意算数类型转换为一个 string 对象。
string str1{ to_string( true ) };
cout << str1 << endl; //输出 1
string str2{ to_string('A') };
cout << str2 << endl; //输出 65
string str3{ to_string(12345) };
cout << str3 << endl;
string str4{ to_string(3.1415926) };
cout << str4 << endl;
将一个 string 对象转换为算数类型 :
- string 参数中第一个非空白符必须是符号(
+
或-
)或数字;但它可以以0x
或0X
开头来表示十六进制数。 - 对那些将字符串转换为浮点值的函数,string 参数也可以以小数点开头,并可以包含
e
或E
来表示指数部分。 - 对于那些将字符串转换为整型值的函数,根据基数不同,string 参数可以包含字母字符,对应大于数字 9 的数。
- 如果 string 不能转换为一个数值,这些函数抛出一个 invalid_argument 异常。