(一)string類(lèi)
1.頭文件
string類(lèi)是由頭文件string支持的,傳統(tǒng)的string.h和cstring僅支持傳統(tǒng)的c風(fēng)格字符串(包括字符串的處理函數(shù)比如strlen等),但不支持string類(lèi)。
2.構(gòu)造string對(duì)象
string字符串的構(gòu)造函數(shù)。
下面列出四種典型的string的構(gòu)造函數(shù):
(1)string(const char * s)將string對(duì)象初始化為s指針指向的NBTS(空字符結(jié)束字符串null-terminated string,也就是c風(fēng)格字符串,字符串常量同樣可以看成是一個(gè)字符指針)。比如string k=string(“how about it?”);
(2)string(size_type n,char c)創(chuàng)建一個(gè)包含n個(gè)元素的string對(duì)象,其中每個(gè)元素被初始化為字符c。比如string k=string(13,‘a(chǎn)’);size_type是一個(gè)依賴(lài)于實(shí)現(xiàn)的整型,是在頭文件string中定義的。
(3)string() 創(chuàng)建一個(gè)默認(rèn)的string對(duì)象,長(zhǎng)度為0,也就是默認(rèn)構(gòu)造函數(shù)。
(4)string(const string &) 將一個(gè)string對(duì)象初始化為另一個(gè)string對(duì)象(也就是復(fù)制構(gòu)造函)。
(5)此外還有幾個(gè)需要了解的構(gòu)造函數(shù):
a,將string對(duì)象初始化為s指針指向的字符串的前n個(gè)字符;
b,string(const string & str,size_type pos=0,size_type n=npos);將string對(duì)象初始化為從str的pos位置開(kāi)始的n個(gè)字符(可能越過(guò)結(jié)尾),或者從pos開(kāi)始之后一直到結(jié)尾的字符(省略后面的兩個(gè)參數(shù)就是復(fù)制構(gòu)造函數(shù))。
c,還有一個(gè)模板類(lèi)型(參數(shù)不一定是c風(fēng)格字符串,還可能是string對(duì)象或其它)的構(gòu)造函數(shù),一般是利用兩個(gè)指針表示的迭代器(迭代器是應(yīng)用于容器類(lèi)的廣義化指針,比如begin和end是兩個(gè)迭代器,那么一般表示[begin,end),即begin是開(kāi)始位置,end是結(jié)束位置的后一個(gè)位置)來(lái)截取部分內(nèi)容作為string對(duì)象的內(nèi)容來(lái)構(gòu)造string對(duì)象。比如s是一個(gè)字符數(shù)組名char s[20]="how are you!";那么可以用string str4=string(s,s+5);來(lái)構(gòu)造string對(duì)象,內(nèi)容為“how ”。
(6)c++11還提供了移動(dòng)構(gòu)造函數(shù)和初始化列表語(yǔ)法,移動(dòng)構(gòu)造函數(shù)后面再講;列表初始化就是說(shuō)可以使用如下方式來(lái)初始化string對(duì)象,string str5{'a','b','o','u','t'};。
重載的+=運(yùn)算符將在string對(duì)象后面加上字符串,比如one+=“ok?”;或one+=two;其中one和two都是string對(duì)象。=運(yùn)算符也可以被重載,可以使用string,c風(fēng)格字符串,或者char值賦值給string對(duì)象(比如string c='a';就是將字符賦值給string對(duì)象也是可以的)。[]運(yùn)算符,被重載,可以使用數(shù)組訪問(wèn)的方法來(lái)訪問(wèn)string字符串中的字符,比如one[3]。
3.string類(lèi)輸入
(1)c風(fēng)格字符串的輸入
c風(fēng)格字符串其實(shí)就是以0結(jié)尾的字符數(shù)組,對(duì)于c字符串的輸入,有三種方式:比如info[100]是一個(gè)字符數(shù)組,則cin>>info;表示輸入一個(gè)字符串(也就是以空白區(qū)分開(kāi)的字符序列,cin會(huì)忽略掉空白,但是不會(huì)刪除末尾的空白,也就是說(shuō)遇到空白,cin>>會(huì)忽略掉并從不是空白的地方開(kāi)始輸入直到遇到下一個(gè)空白,并將空白留在隊(duì)列之中,空白也包括回車(chē)符);cin.getline(info,100);輸入一行,最大長(zhǎng)度100,輸入后丟掉回車(chē)字符,也就是本字符串中沒(méi)有回車(chē),而輸入緩沖區(qū)也沒(méi)有回車(chē)符,如果長(zhǎng)度超過(guò)100,就會(huì)設(shè)置標(biāo)志位阻斷輸入(getline函數(shù)主要是為了按行輸入,如果因?yàn)檩斎胄凶址喽鴽](méi)有能夠輸入一行,就會(huì)阻斷從而可以判斷是否讀取了一整行);cin.get(info,100);輸入一行,將回車(chē)符留在隊(duì)列之中,如果下次接著使用cin.get函數(shù)來(lái)輸入,則不會(huì)有顯示,因?yàn)榛剀?chē)符一直留在緩沖區(qū)中,此時(shí)需要用cin.get()函數(shù)將下一個(gè)字符(也就是回車(chē)字符)丟棄,然后再用cin.get(info,100)來(lái)繼續(xù)讀取數(shù)據(jù)(如果get函數(shù)啥也沒(méi)get到,也就是說(shuō)輸入的是一個(gè)空行,那么get函數(shù)也會(huì)設(shè)置阻斷,表示沒(méi)有讀取到任何內(nèi)容),cin.get(info,100);這樣的函數(shù)當(dāng)輸入超過(guò)100的時(shí)候,不會(huì)設(shè)置阻斷,只是會(huì)將其他內(nèi)容放到緩沖區(qū)中。
(2)string對(duì)象的輸入
對(duì)于string對(duì)象的輸入。有兩種方式,一種是直接>>輸入運(yùn)算符,cin>>stuff;(這種方式同樣是忽略空白);另一種是getline函數(shù),如getline(cin,stuff);getline函數(shù)將會(huì)自動(dòng)調(diào)整string的大小來(lái)適應(yīng)輸入。
(3)區(qū)別
c風(fēng)格字符串的輸入方法是istream類(lèi)的方法,而string版本的輸入方法是獨(dú)立的函數(shù),因此c風(fēng)格字符串輸入要用對(duì)象加.的方式;而string輸入函數(shù)直接用函數(shù)名,參數(shù)是istream對(duì)象cin和string對(duì)象。
(4)可選參數(shù)作為分界符
??? 兩個(gè)版本的getline函數(shù)都有一個(gè)可選的參數(shù),用來(lái)指明用什么符號(hào)作為輸入的分界符(就像回車(chē)一樣,回車(chē)就是默認(rèn)的分界符)。格式如下:cin.getline(info,100,’:’);getline(cin,stuff,’:’);。還有一點(diǎn)需要注意的是,不論哪個(gè)版本的getline,也不論分隔符是多少,getline函數(shù)都會(huì)舍棄分隔符(而get函數(shù)會(huì)將回車(chē)留在輸入隊(duì)列中)。
(5)深入了解string對(duì)象的輸入
String對(duì)象的大小限制問(wèn)題:string字符串大小是由最大允許長(zhǎng)度來(lái)控制的,由常量string::npos指定;而另一個(gè)限制因素是可以使用的內(nèi)存量。
getline函數(shù)的輸入問(wèn)題:getline()函數(shù)從輸入中讀取字符,并將其存儲(chǔ)到目標(biāo)string對(duì)象之中,直到發(fā)生下列三種情況之一:一是遇到文件末尾,fail()和eof()都會(huì)返回true值。二是遇到分界符(默認(rèn)為回車(chē)),會(huì)把分界符丟棄,并不存儲(chǔ)它。三是存儲(chǔ)的字符達(dá)到最大允許值(string::npos和最大內(nèi)存中的較小者),此時(shí)將設(shè)置輸入流的failbit位,也即是fail()函數(shù)將返回true,而eof()函數(shù)不返回true。
輸入流對(duì)象的統(tǒng)計(jì)系統(tǒng):輸入流對(duì)象有一個(gè)統(tǒng)計(jì)系統(tǒng),用于跟蹤流的錯(cuò)誤狀態(tài),遇到文件尾的時(shí)候eofbit寄存器被設(shè)置,檢查到輸入錯(cuò)誤(比如類(lèi)型不匹配等)failbit寄存器設(shè)置,檢測(cè)到無(wú)法識(shí)別故障,設(shè)置badbit寄存器,一切順利設(shè)置goodbit寄存器。
4.使用字符串
我們已經(jīng)了解了不同方式string對(duì)象的創(chuàng)建,顯示string對(duì)象的內(nèi)容,將數(shù)據(jù)讀取和附加到string對(duì)象中,給string對(duì)象賦值,將兩個(gè)string對(duì)象連接起來(lái)。其他的string對(duì)象的功能:
(1)比較字符串:string對(duì)六個(gè)關(guān)系運(yùn)算符進(jìn)行了重載,可以按照編碼順序對(duì)字符串進(jìn)行比較。而原始的c語(yǔ)言字符串中要使用各種函數(shù)來(lái)對(duì)字符串進(jìn)行對(duì)比,比如strcmp()函數(shù)等。
(2)確定字符串的長(zhǎng)度:size()和length()成員函數(shù)都返回字符串中的字符數(shù)。比如snake1.length(),snake2.size()等(這是因?yàn)閘ength()函數(shù)是string類(lèi)本來(lái)就有的,而size()函數(shù)是為了能夠兼容STL)。
(3)可以以多種不同的方式在字符串中搜索給定的子字符串和字符:使用find()方法,有四個(gè)版本的重載。string::npos是字符串可以存儲(chǔ)的最大字符數(shù)。
size_type find(const string & string,size_type pos=0)const;從string對(duì)象的pos位置開(kāi)始查找string字符串,如果找到,返回首字符的位置索引,如果沒(méi)有找到,返回string::npos。
size_type find(const char * s,size_type pos=0)const;作用同上,不過(guò)查找的是c風(fēng)格的字符串。
size_type find(const char * s,size_type pos=0,size_type n);比上面多了一個(gè)參數(shù),表示從pos開(kāi)始,查找s前n個(gè)字符組成的子字符串,同樣,找到就返回第一個(gè)字符的索引,如果沒(méi)有找到,就返回string::npos。
size_type find(char ch,size_type pos=0)const;作用是從pos位置開(kāi)始,查找字符ch。
(4)其他類(lèi)似find()的方法:rfind()方法查找字符串或字符最后出現(xiàn)的位置。find_first_of(),find_last_of()分別表示查找參數(shù)字符串或字符的任一個(gè)字符第一次和最后一次出現(xiàn)的位置。Find_first_not_of(),find_last_not_of(),分別表示在字符串中查找第一個(gè)和最后一個(gè)不包含在參數(shù)字符串中的字符,并返回其位置。
(5)字符串的其他不太常用的功能:
string對(duì)象的長(zhǎng)度是動(dòng)態(tài)改變的,一般在分配內(nèi)存的時(shí)候會(huì)給一個(gè)適當(dāng)大一點(diǎn)的空間,以便string對(duì)象能進(jìn)行擴(kuò)展,如果不夠用,就會(huì)再分配一個(gè)是原空間大小的兩倍的空間。capacity()方法返回當(dāng)前分配給字符串的內(nèi)存塊的大小,而reserve()方法讓你能夠請(qǐng)求內(nèi)存塊的最小長(zhǎng)度,也就是將字符串的容量設(shè)置為至少size(參數(shù))。比如zero為一個(gè)string對(duì)象,則zero.reserve(50);表示zero長(zhǎng)度至少為50(實(shí)際仍然會(huì)分配一個(gè)大于50的特定數(shù),比如63)。
open()打開(kāi)文件的方法要求一個(gè)c風(fēng)格的字符串作為參數(shù),那如果要打開(kāi)存儲(chǔ)在string對(duì)象中的文件名的文件怎么辦呢?c_str()方法返回一個(gè)指向c風(fēng)格字符串的指針,可以作為open的參數(shù)。比如:fout.open(filename.c_str());
5.字符串種類(lèi)
string庫(kù)實(shí)際上是一個(gè)基于模板類(lèi)的,模板basic_string一共有四個(gè)具體化,string其實(shí)是typedef basic_string<char> string;也就是basic_string的一個(gè)具體化而已。另外三個(gè)具體化是:typedef basic_string<wchar_t> wstring;typedef basic_string<char16_t> u16string;typedef basic_string<char32_t> u32string;
