第十六章 string類和標準模板庫(1)string類

(一)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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章