string类
string类是由头文件string支持的(头文件string.h和cstring支持对C-风格字符串进行操纵的C库字符串函数,但不支持string类)。
构造函数
string类一共有6个构造函数(ctor,这是传统C++中构造函数的缩写)。类中将string::npos定义为字符串的最大长度,通常为无符号int的最大值。
string实际上是模板规范basic_string<char>的一个typedef。
size_type是一个依赖于实现的整型,在头文件string中定义。
NBTS是(null-byte-terminated string)的缩写,表示以空字符结束的字符串——传统的C字符串。
最后一个构造函数有一个模板参数:
template<class Iter> string(Iter begin,Iter end);
通常,begin和end可以是迭代器——广泛用于STL中的广义化指针。该ctor用于数组时: srting(array+3,array+10);将用array[3]至array[9]的值初始化string对象(因为数组名相当于指针)。用于string对象(假设为string_ob): string(&string_ob[3],&string_ob[10]); 由于对象名不会被看做是对象的地址,而string_ob[3]因为[]被重载,所以返回的是一个char值。因此使用地址操作符 & 后,被当做指针对待。
该类还重载了+=操作符,它将一个字符串附加到另一个字符串的后面;重载的=操作符用于将一个字符串赋给另一个字符串;重载的<<操作符用于显示string对象;重载的[]操作符用于访问字符串中的各个字符。
string类输入
对于C-字符串,有3中输入方式:
char info[100];
cin>>info; // read a word
cin.getline(info,100); // read a line,discard /n
cin.get(info,100); // read a line,leave /n in queue
对于string对象,有两种输入方式:
string stuff;
cin>>stuff; // read a word
getline(cin,stuff); // read a line,discard /n
两个版本的getline()都有一个可选参数,用于指定使用哪个字符来确定输入的边界:
cin.getline(info,100,':'); //read up to :,discard :
getline(stuff,':'); //read up to :,discard :
string版本的getline()将自动调整目标string对象的大小,使之刚好能够存储输入的字符。这使得无需指定读取多少个字符的数值参数。
读取C-风格字符串的函数是istream类的方法(cin是调用对象),而string版本是独立的函数(cin是一个传递的函数参数)。
这种规则也适用于>>形式:
cin.operator>>(fname); // ostream class method
operator>>(cin,lname); // regular function
string版本的getline()读取输入的结束条件:
(1) 到达文件尾,这种情况下,输入流的eofbit将被设置,意味着方法fail()和eof()都将返回true。
(2) 遇到分界字符(默认为/n),这种情况下,将把分界字符从输入流中删除,但不存储它。
(3) 读取的字符数打到最大允许值(string::npos和可供分配的内存字节数种较小的一个),这种情况下,将设置输入流的failbit,意味着方法fail()将返回true。
输入流对象有一个统计系统,用于跟踪流的错误状态。检测到文件尾后将设置eofbit寄存器,检测到输入错误时将设置failbit寄存器,出现无法识别的故障时将设置badbit寄存器,一切顺利时将设置goodbit寄存器。
关于输入流对象状态寄存器的更多详细介绍请查看<<cin深入分析(下) - cin的错误处理>>。
string版本的operator>>()函数,它不断读取,直到遇到空白字符并将其留在输入队列中。空白字符指的是空格、换行符和制表符,普遍地说,是任何将其作为参数来调用isspace()时,该函数返回true的字符。
(指定了分界字符后,非分界字符将被视为常规字符,比如将换行符读为常规字符)
使用字符串
string对象对全部6个关系操作符都进行了重载。其中每个关系操作符都以三种方式被重载,使其能够将string对象与另一个string对象、C-风格字符串进行比较,并能够将C-风格字符串与string对象进行比较。
size()和length()成员函数都可以返回字符串中的字符数。length()成员来自较早版本的string类,而size()则是为提供STL兼容性而添加的。
下表简要地描述了find()方法的4个版本
string库还提供了相关的方法: rfind()、find_first_of()、find_last_of()、find_first_not_of()和find_last_not_of(),它们的重载函数特征标都与find()方法相同。
rfind()方法查找子字符串或字符最后一次出现的位置。
find_first_of()方法在字符串中查找参数中任何一个字符首次出现的位置。例如:
int where = snake1.find_first_of("hark");
将返回r在"cobra"中的位置(即索引3),因为这是"hark"中各个字母在"cobra"首次出现的位置。
find_last_of()方法的功能与此相同,只是它查找的是最后一次出现的位置。因此,语句:
int where = snake1.find_last_of("hark");
将返回a在"cobra"中的位置。
find_first_not_of()方法在字符串中查找第一个不被包含在参数中的字符:
int where = snake1.find_first_not_of("hark");
将返回c在"cobra"中的位置,因为"hark"中没有c。
find_last_not_of()方法的功能与此相同,只是它查找的是最后一个,因此,语句:
int where = snake1.find_last_not_of("hark");
将返回b在"cobra"中的位置。
string对象内存分配
string对象能够自动调节内存大小。因此很多C++实现将分配一个比实际字符串大的内存块,为字符串提供了增大空间。然而,如果字符串不断增大,超过了内存块的大小,程序将分配一个大小为原来两倍的新内存块,以提供足够的增大空间,避免不断的分配新的内存块。
方法capacity()返回当前分配给字符串的内存块的大小(单位为字节):
string_Object.capacity();
方法reserve()使其能够请求内存块的最小长度(单位为字节):
string_Object.reserve(100);
c_str()方法返回一个指向C-风格字符串的指针:
string filename;
cout<<"Enter file name: ";
cin>>filename;
ofstream fout;
fout.open(filename.c_str());
(open()方法要求使用一个C-风格字符串作为参数)
重载C函数以使用string对象
比较两个字符串是否相等,不区分大小写:
boot stricmp(const string & strA,const string & strB)
{ return stricmp (strA.c_str(),strB.c_str() ) == 0; }
由此可见,c_str()方法提供了一条将C-风格字符串函数转换为string对象函数的路径。
关于string类的更多方法,请查看<<string类方法介绍>>