(一)string类
1.头文件
string类是由头文件string支持的,传统的string.h和cstring仅支持传统的c风格字符串(包括字符串的处理函数比如strlen等),但不支持string类。
2.构造string对象
string字符串的构造函数。
下面列出四种典型的string的构造函数:
(1)string(const char * s)将string对象初始化为s指针指向的NBTS(空字符结束字符串null-terminated string,也就是c风格字符串,字符串常量同样可以看成是一个字符指针)。比如string k=string(“how about it?”);
(2)string(size_type n,char c)创建一个包含n个元素的string对象,其中每个元素被初始化为字符c。比如string k=string(13,‘a’);size_type是一个依赖于实现的整型,是在头文件string中定义的。
(3)string() 创建一个默认的string对象,长度为0,也就是默认构造函数。
(4)string(const string &) 将一个string对象初始化为另一个string对象(也就是复制构造函)。
(5)此外还有几个需要了解的构造函数:
a,将string对象初始化为s指针指向的字符串的前n个字符;
b,string(const string & str,size_type pos=0,size_type n=npos);将string对象初始化为从str的pos位置开始的n个字符(可能越过结尾),或者从pos开始之后一直到结尾的字符(省略后面的两个参数就是复制构造函数)。
c,还有一个模板类型(参数不一定是c风格字符串,还可能是string对象或其它)的构造函数,一般是利用两个指针表示的迭代器(迭代器是应用于容器类的广义化指针,比如begin和end是两个迭代器,那么一般表示[begin,end),即begin是开始位置,end是结束位置的后一个位置)来截取部分内容作为string对象的内容来构造string对象。比如s是一个字符数组名char s[20]="how are you!";那么可以用string str4=string(s,s+5);来构造string对象,内容为“how ”。
(6)c++11还提供了移动构造函数和初始化列表语法,移动构造函数后面再讲;列表初始化就是说可以使用如下方式来初始化string对象,string str5{'a','b','o','u','t'};。
重载的+=运算符将在string对象后面加上字符串,比如one+=“ok?”;或one+=two;其中one和two都是string对象。=运算符也可以被重载,可以使用string,c风格字符串,或者char值赋值给string对象(比如string c='a';就是将字符赋值给string对象也是可以的)。[]运算符,被重载,可以使用数组访问的方法来访问string字符串中的字符,比如one[3]。
3.string类输入
(1)c风格字符串的输入
c风格字符串其实就是以0结尾的字符数组,对于c字符串的输入,有三种方式:比如info[100]是一个字符数组,则cin>>info;表示输入一个字符串(也就是以空白区分开的字符序列,cin会忽略掉空白,但是不会删除末尾的空白,也就是说遇到空白,cin>>会忽略掉并从不是空白的地方开始输入直到遇到下一个空白,并将空白留在队列之中,空白也包括回车符);cin.getline(info,100);输入一行,最大长度100,输入后丢掉回车字符,也就是本字符串中没有回车,而输入缓冲区也没有回车符,如果长度超过100,就会设置标志位阻断输入(getline函数主要是为了按行输入,如果因为输入行字符太多而没有能够输入一行,就会阻断从而可以判断是否读取了一整行);cin.get(info,100);输入一行,将回车符留在队列之中,如果下次接着使用cin.get函数来输入,则不会有显示,因为回车符一直留在缓冲区中,此时需要用cin.get()函数将下一个字符(也就是回车字符)丢弃,然后再用cin.get(info,100)来继续读取数据(如果get函数啥也没get到,也就是说输入的是一个空行,那么get函数也会设置阻断,表示没有读取到任何内容),cin.get(info,100);这样的函数当输入超过100的时候,不会设置阻断,只是会将其他内容放到缓冲区中。
(2)string对象的输入
对于string对象的输入。有两种方式,一种是直接>>输入运算符,cin>>stuff;(这种方式同样是忽略空白);另一种是getline函数,如getline(cin,stuff);getline函数将会自动调整string的大小来适应输入。
(3)区别
c风格字符串的输入方法是istream类的方法,而string版本的输入方法是独立的函数,因此c风格字符串输入要用对象加.的方式;而string输入函数直接用函数名,参数是istream对象cin和string对象。
(4)可选参数作为分界符
两个版本的getline函数都有一个可选的参数,用来指明用什么符号作为输入的分界符(就像回车一样,回车就是默认的分界符)。格式如下:cin.getline(info,100,’:’);getline(cin,stuff,’:’);。还有一点需要注意的是,不论哪个版本的getline,也不论分隔符是多少,getline函数都会舍弃分隔符(而get函数会将回车留在输入队列中)。
(5)深入了解string对象的输入
String对象的大小限制问题:string字符串大小是由最大允许长度来控制的,由常量string::npos指定;而另一个限制因素是可以使用的内存量。
getline函数的输入问题:getline()函数从输入中读取字符,并将其存储到目标string对象之中,直到发生下列三种情况之一:一是遇到文件末尾,fail()和eof()都会返回true值。二是遇到分界符(默认为回车),会把分界符丢弃,并不存储它。三是存储的字符达到最大允许值(string::npos和最大内存中的较小者),此时将设置输入流的failbit位,也即是fail()函数将返回true,而eof()函数不返回true。
输入流对象的统计系统:输入流对象有一个统计系统,用于跟踪流的错误状态,遇到文件尾的时候eofbit寄存器被设置,检查到输入错误(比如类型不匹配等)failbit寄存器设置,检测到无法识别故障,设置badbit寄存器,一切顺利设置goodbit寄存器。
4.使用字符串
我们已经了解了不同方式string对象的创建,显示string对象的内容,将数据读取和附加到string对象中,给string对象赋值,将两个string对象连接起来。其他的string对象的功能:
(1)比较字符串:string对六个关系运算符进行了重载,可以按照编码顺序对字符串进行比较。而原始的c语言字符串中要使用各种函数来对字符串进行对比,比如strcmp()函数等。
(2)确定字符串的长度:size()和length()成员函数都返回字符串中的字符数。比如snake1.length(),snake2.size()等(这是因为length()函数是string类本来就有的,而size()函数是为了能够兼容STL)。
(3)可以以多种不同的方式在字符串中搜索给定的子字符串和字符:使用find()方法,有四个版本的重载。string::npos是字符串可以存储的最大字符数。
size_type find(const string & string,size_type pos=0)const;从string对象的pos位置开始查找string字符串,如果找到,返回首字符的位置索引,如果没有找到,返回string::npos。
size_type find(const char * s,size_type pos=0)const;作用同上,不过查找的是c风格的字符串。
size_type find(const char * s,size_type pos=0,size_type n);比上面多了一个参数,表示从pos开始,查找s前n个字符组成的子字符串,同样,找到就返回第一个字符的索引,如果没有找到,就返回string::npos。
size_type find(char ch,size_type pos=0)const;作用是从pos位置开始,查找字符ch。
(4)其他类似find()的方法:rfind()方法查找字符串或字符最后出现的位置。find_first_of(),find_last_of()分别表示查找参数字符串或字符的任一个字符第一次和最后一次出现的位置。Find_first_not_of(),find_last_not_of(),分别表示在字符串中查找第一个和最后一个不包含在参数字符串中的字符,并返回其位置。
(5)字符串的其他不太常用的功能:
string对象的长度是动态改变的,一般在分配内存的时候会给一个适当大一点的空间,以便string对象能进行扩展,如果不够用,就会再分配一个是原空间大小的两倍的空间。capacity()方法返回当前分配给字符串的内存块的大小,而reserve()方法让你能够请求内存块的最小长度,也就是将字符串的容量设置为至少size(参数)。比如zero为一个string对象,则zero.reserve(50);表示zero长度至少为50(实际仍然会分配一个大于50的特定数,比如63)。
open()打开文件的方法要求一个c风格的字符串作为参数,那如果要打开存储在string对象中的文件名的文件怎么办呢?c_str()方法返回一个指向c风格字符串的指针,可以作为open的参数。比如:fout.open(filename.c_str());
5.字符串种类
string库实际上是一个基于模板类的,模板basic_string一共有四个具体化,string其实是typedef basic_string<char> string;也就是basic_string的一个具体化而已。另外三个具体化是:typedef basic_string<wchar_t> wstring;typedef basic_string<char16_t> u16string;typedef basic_string<char32_t> u32string;