string 类型支持长度可变的字符串,C++ 标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作。标准库 string 类型的目的就是满足对字符串的一般应用。
一、string对象的定义和初始化
#include <iostream>
#include<string>
#include<cctype>
using namespace std;
int main()
{
char cp[]="as1254884adas";
string a;//默认构造函数a为空串
string a1("12345p->=");//将a1初始化为一个字符串字面值副本
string a2(a1);//将a2初始化为a1的一个副本
string a3(5,'a');//将a3初始化为字符'a'的5个副本
string a4(cp,5);//创建一个 string 对象,它被初始化为 cp 所指向数组的前 5 个元素的副本
string a5(a1,3);//创建一个 string 对象,它被初始化为一个已存在的 string 对象 a1 中从下标 3 开始的字符的副本
//函数原型:string a6(a1, pos2, len2 创建一个 string 对象,它被初始化为 a1 中从下标 pos2 开始的 len2 个字符的副本。
//如果 pos2 > a1.size(),则该操作未定义,无论 len2 的值是多少,最多只能复制 a1.size() - pos2 个字符
string a6(a1,2,3);
cout<<a<<endl;
cout<<a1<<endl<<a2<<endl<<a3<<endl<<a4<<endl;
cout<<a5<<endl<<a6<<endl;
return 0;
}
二、string对象的读写
我们可以用 iostream 和 string 标准库,使用标准输入输出操作符来读写 string 对象,和内置类型的输入操作(cin>>s)一样,string 的输入操作符也会返回所读的数据流。因此,可以把输入操作作为判断条件,请注意:从标准输入读取 string 并将读入的串存储在 s 中,读取并忽略开头所有的空白字符(如空格,换行符,制表符)。读取字符直至再次遇到空白字符,读取终止。
当然,我们还可以使用getline函数读取整行文本,这个函数接受两个参数:一个输入流对象和一个 string 对象。getline 函数从输入流的下一行读取,并保存读取的内容到不包括换行符。和输入操作符不一样的是,getline 并不忽略行开头的换行符。只要 getline 遇到换行符,即便它是输入的第一个字符,getline 也将停止读入并返回。如果第一个字符就是换行符,则 string 参数将被置为空 string。
代码如下:
#include <iostream>
#include<string>
#include<cctype>
using namespace std;
int main()
{
string line,s;
if(cin>>s)
cout<<"s:"<<s<<endl;
if(getline(cin,line))
cout<<"line:"<<line<<endl;
return 0;
}
三、string对象的常用操作
==,!=, <, <=, >, 和 >=保持这些操作符的含义,需要说明的是:string 对象比较操作是区分大小写的,即同一个字符的大小写形式被认为是两个不同的字符。在多数计算机上,大写的字母位于小写之前:任何一个大写之母都小于任意的小写字母。下面探讨下string的size和empty操作。
1.size函数和empty函数
empty函数用于判断string对象是否为空,其函数返回值为bool值。
size函数获取string对象中字符的个数(size与0比较也可以判断是否为空),常应用于下标寻寻值操作。从逻辑上来讲,size()函数似乎应该返回整形数值(也可以赋值给int类型),但事实上,size 操作返回的是 string::size_type 类型的值。使用 int 变量的另一个问题是,有些机器上 int 变量的表示范围太小,甚至无法存储实际并不长的 string 对象。如在有 16 位 int 型的机器上,int 类型变量最大只能表示 32767 个字符的 string 个字符的 string 对象。而能容纳一个文件内容的 string 对象轻易就会超过这个数字。因此,为了避免溢出,保存一个 stirng 对象 size 的最安全的方法就是使用标准库类型 string::size_type。
下面是string对象字符的处理函数(c为单个字符,可用string下标表示):
isalnum(c) | 如果 c 是字母或数字,则为 True。 |
isalpha(c) | 如果 c 是字母,则为 true。 |
iscntrl(c) | 如果 c 是控制字符,则为 true |
isdigit(c) | 如果 c 是数字,则为 true。 |
isgraph(c) | 如果 c 不是空格,但可打印,则为 true。 |
islower(c) | 如果 c 是小写字母,则为 true。 |
isprint(c) | 如果 c 是可打印的字符,则为 true。 |
ispunct(c) | 如果 c 是标点符号,则 true。 |
isspace(c) | 如果 c 是空白字符,则为 true。 |
isupper(c) | 如果 c 是大写字母,则 true。 |
isxdigit(c) | 如果是 c 十六进制数,则为 true。 |
tolower(c) | 如果 c 大写字母,返回其小写字母形式,否则直接返回 c。 |
toupper(c) | 如果 c 是小写字母,则返回其大写字母形式,否则直接返回 c。 |
#include <iostream>
#include<string>
#include<cctype>
using namespace std;
int main()
{
char cp[]="as1254884adas";
string a;//默认构造函数a为空串
string a1("12345p->=");//将a1初始化为一个字符串字面值副本
string a2(a1);//将a2初始化为a1的一个副本
string a3(5,'a');//将a3初始化为字符'a'的5个副本
string a4(cp,5);//创建一个 string 对象,它被初始化为 cp 所指向数组的前 5 个元素的副本
cout<<a4.empty()<<endl;//如果 a4 为空串,则返回 true,否则返回 false。
cout<<a1.size()<<endl;//返回 a1 中字符的个数
cout<<a1[1]<<endl; //返回 a1 中位置为 n 的字符,位置从 0 开始计数
//把 a1 和a3 连接成一个新字符串,返回新生成的字符串。
//当然也可以和字符串字面值相连接,即:a1+"sdasd";
cout<<(a1+a3)<<endl;
a1=a3; //把 a1 内容替换为 a3 的副本
cout<<a1<<endl;
cout<<(a1==a3)<<endl;
string::size_type i=0;
for(;i<a1.size();++i)
{
cout<<a1[i]<<endl;
}
cout<<i<<endl;
return 0;
}
2. compare函数比较大小操作
操作符逐个字符地进行比较,直到比较到某个位置上,两个 string 对象对应的字符不相同为止。string 对象的整个比较依赖于不相同字符之间的比较。如果第一个不相等的字符是‘e’和‘o’。由于在英文字母表中,‘e’出现得比‘o’早(即‘e’小于‘o’),于是“abend”小于“abort”。如果要比较的两个 string 对象长度不相同,而且一个 string 对象是另一个 string 对象的子串,则较短的 string 对象小于较长的 string 对象。compare函数实现的字典顺序比较与以上相同。
compare函数返回下面列出的三种可能值之一:
2.1. 正数,此时 s1 大于 args 所代表的 string 对象。
2.2. 负数,此时 s1 小于 args 所代表的 string 对象。
2.3. 0,此时 s1 恰好等于 args 所代表的 string 对象。
下面是compare的一些重载函数:
s.compare(s2) | 比较 s 和 s2 |
s.compare(pos1, n1, s2) | 让 s 中从 pos 下标位置开始的 n1 个字符与 s2 做比较 |
s.compare(pos1, n1, s2, pos2, n2) | 让 s 中从 pos1 下标位置开始的 n1 个字符与 s2 中从 pos2 下标位置开始的 n2 个字符做比较 |
s.compare(cp) | 比较 s 和 cp 所指向的以空字符结束的字符串 |
s.compare(pos1, n1, cp) | 让 s 中从 pos1 下标位置开始的 n1 个字符与 cp 所指向的字符串做比较 |
s.compare(pos1, n1, cp, n2) | 让 s 中从 pos1 下标位置开始的 n1 个字符与 cp 所指向的字符串的前 n2 个字符做比较 |
3.string的查找操作
string 类提供了 6 种查找函数,每种函数以不同形式的 find 命名。这些操作全都返回 string::size_type 类型的值,以下标形式标记查找匹配所发生的位置;或者返回一个名为 string::npos 的特殊值,说明查找没有匹配。string 类将 npos 定义为保证大于任何有效下标的值。
s.find( args) | 在 s 中查找 args 的第一次出现 |
s.rfind( args) | 在 s 中查找 args 的最后一次出现 |
s.find_first_of( args) | 在 s 中查找 args 的任意字符的第一次出现 |
s.find_last_of( args) | 在 s 中查找 args 的任意字符的最后一次出现 |
s.find_first_not_of( args) | 在 s 中查找第一个不属于 args 的字符 |
s.find_last_not_of( args) | 在 s 中查找最后一个不属于 args 的字符 |
string类型提供的find操作的参数args:
c, pos | 在 s 中,从下标 pos 标记的位置开始,查找字符 c。pos 的默认值为 0 |
s2, pos | 在 s 中,从下标 pos 标记的位置开始,查找 string 对象 s2。pos 的默认值为 0 |
cp, pos | 在 s 中,从下标 pos 标记的位置形参,查找指针 cp 所指向的 C 风格的以空字符结束的字符串。pos 的默认值为 0 |
cp, pos, n | 在 s 中,从下标 pos 标记的位置开始,查找指针 cp 所指向数组的前 n 个字符。pos 和 n 都没有默认值 |
4.append 和 replace 函数
string 类型提供了 6 个 append 重载函数版本和 10 个 replace 版本。append 和 replace 函数使用了相同的参数集合实现重载。用于指定在 string 对象中添加的字符。对于 append 操作,字符将添加在 string 对象的末尾。而 replace 函数则将这些字符插入到指定位置,从而替换 string 对象中一段已存在的字符。
s.append( args) | 将 args 串接在 s 后面。返回 s 引用 |
s.replace(pos, len, args) | 删除 s 中从下标 pos 开始的 len 个字符,用 args 指定的字符替换之。返回 s 的引用 |
s.replace(b, e, args) | 删除迭代器 b 和 e 标记范围内所有的字符,用 args 替换之。返回 s 的引用 |
各个参数操作:
s2 | string 类型的字符串 s2 |
s2, pos2, len2 | 字符串 s2 中从下标 pos2 开始的 len2 个字符 |
cp | 指针 cp 指向的以空字符结束的数组 |
cp, len2 | cp 指向的以空字符结束的数组中前 len2 个字符 |
n, c | 字符 c 的 n 个副本 |
b2, e2 | 迭代器 b2 和 e2 标记的范围内所有字符 |
5.子串操作
s.substr(pos, n) | 返回一个 string 类型的字符串,它包含 s 中从下标 pos 开始的 n 个字符 |
s.substr(pos) | 返回一个 string 类型的字符串,它包含从下标 pos 开始到 s 末尾的所有字符 |
s.substr() | 返回 s 的副本 |
关于string支持的容器操作详情,请查看下篇文章。。。。。。