第四章 復(fù)合類型(2)字符串

(二)字符串

??? c++有兩種類型的字符串跑筝,一種是基于c語言的死讹,另一種是c++中的string類(嚴(yán)格來說string類不是通常意義上的字符串,也就是數(shù)組曲梗,而是用來表示字符串的字符串類)赞警。

1.c風(fēng)格的字符串

??? 什么是c風(fēng)格字符串?c風(fēng)格字符串有一個特殊的性質(zhì)愧旦,以空字符(null character)結(jié)尾,空字符寫作\0(實際上就是ASCII碼編號為零的字符)碘举。C風(fēng)格字符串在C和C++中都是支持的忘瓦。

??? c風(fēng)格字符串的聲明和初始化:采用字符數(shù)組的方式:比如char dog[4]={‘d’,’o’,’g’,’\0’}(初始化列表方法),聲明了一個長度為4的字符數(shù)組,字符依次為d耕皮,o境蜕,g,\0凌停,由于在結(jié)尾有一個\0粱年,因此程序?qū)⑦@個字符數(shù)組看成是字符串(就是說字符串以\0為結(jié)尾標(biāo)志);另外一種更簡單的初始化方法為使用字符串常量,即將字符串用雙引號引起來罚拟,上面的例子可以寫成char dog[]=”dog”(這種寫法相當(dāng)于大括號式的初始化列表的方法{dog}台诗,只不過大括號形式的寫法可以省略等號,這種形式不能省略等號);

2.注意的問題:

(1)用引號引起來的字符串隱式地包含了結(jié)尾的空字符\0赐俗。因此在確定存儲字符串所需的最短數(shù)組長度時拉队,別忘了將結(jié)尾的空字符計算在內(nèi)(數(shù)組長度等于字符數(shù)目加一,但一般我們將這份工作交給編譯器自動運行阻逮,即不加中括號里面的字符數(shù)組的長度粱快,比如上面例子里的數(shù)組長度4,而讓程序自己計算)叔扼。

(2)字符串常量不能與字符常量互換事哭,比如“a”就不等于‘a(chǎn)’,因為字符串“a”隱式地包含了\0瓜富,是一個數(shù)組鳍咱,更確切的說是一個字符數(shù)組的指針,而‘a(chǎn)’就表示a的編碼与柑,是一個字符(本質(zhì)是字符的編碼)谤辜。

(3)拼接字符串常量。

??? c++允許拼接字符串字面值仅胞,即將兩個用引號括起的字符串合并為一個每辟。事實上,任何兩個由空白(空格干旧、制表符和換行符)分隔的字符串常量都將自動拼接成一個。比如妹蔽,cout <<“how are”? “you”;不管中間的空白是空格符椎眯,制表符還是換行符,這兩個字符串都將輸出“how areyou”,注意這里沒有漏寫空格胳岂,程序就是會無縫連接编整。這里的機(jī)理就是將第一個字符串的最后面的\0去掉,然后緊跟著后一個字符串乳丰,后一個字符串末尾的\0作為整個新的字符串常量的結(jié)尾標(biāo)記掌测。

(4)字符串長度函數(shù)。有特殊的用于計算字符串長度的函數(shù)strlen()产园,要使用這個函數(shù)需要包含頭文件cstring汞斧,即#include <cstring>(這是標(biāo)準(zhǔn)C語言函數(shù)庫中的頭文件)夜郁。比如:char a[]=”dog”;cout<<a;b=strlen(a);cout<<b;結(jié)果將會輸出dog3(表示字符串有三個字符,當(dāng)然你認(rèn)為是3byte也可以粘勒,因為一個字符占用一個byte)竞端。

(5)需要特別注意strlen()函數(shù)與sizeof運算符的區(qū)別,sizeof()返回的是整個數(shù)組(數(shù)據(jù))的長度庙睡,而strlen返回的是字符串的長度事富,并且strlen()不會把結(jié)尾的\0計入長度范圍。什么意思呢乘陪?舉個例子:char a[]=”dog\0hello”;cout<<sizeof(a);會輸出什么呢统台?實測的結(jié)果是10,因為sizeof()運算符把所有的字符(包括中間那個\0)和結(jié)尾的\0都算進(jìn)去了啡邑,測的是整個字符數(shù)組的長度(字節(jié)byte)饺谬。而如果使用strlen()呢?結(jié)果是3谣拣,也就是計數(shù)了從開頭到第一個\0的長度(因為程序會認(rèn)為這就是一個字符串)募寨,并且\0還不會計算在內(nèi),因此輸出的就是只有dog三個字符的長度了森缠。

3.字符串的輸入問題:

(1)用cin輸入字符串時候會發(fā)生的問題:一是cin指令將空格等空白作為字符串分隔的標(biāo)記拔鹰,這會在輸入名字等中間帶有空格的字符串的時候出現(xiàn)問題。比如贵涵,char str[20];cin>>str;然后我輸入“Ken Thompson”列肢,程序只會在str中存儲“Ken”,整個過程是這樣的宾茂,當(dāng)我們輸入一句話然后回車的時候瓷马,這段話就會進(jìn)入輸入隊列,cin要取得輸入的時候跨晴,會從輸入隊列取第一個單詞(遇到空白即認(rèn)為是取完了一個單詞)欧聘,然后將其他的單詞保留在輸入隊列,如果此時我們再用一次cin輸入端盆,程序會直接讀取剩下的“Thompson”怀骤,而不會要求我們再用鍵盤輸入新內(nèi)容;二是焕妙,cin指令輸入的字符串超過字符數(shù)組的字?jǐn)?shù)限制怎么辦蒋伦。

(2)上面的第一個問題可以使用每次讀取一行的字符串輸入來解決,每次讀入一行的字符串的輸入函數(shù)為getline()和get();其實是面向行的類成員函數(shù)焚鹊,都是屬于cin類痕届,可以用cin對象來調(diào)用,用法為cin.getline(a,b)。getline()函數(shù)讀入后舍去回車符研叫,而get()不舍掉回車符锤窑。

??? cin.getline()有兩個參數(shù)。第一個參數(shù)是用來存儲輸入行的數(shù)組的名稱蓝撇,第二個參數(shù)是要讀取的字符數(shù)(\0計入)(如果這個參數(shù)為20果复,最多讀取19個字符)。用這個函數(shù)會讀取到最大字符數(shù)的位置或換行符的位置渤昌,然后在最后添加空字符\0虽抄,如果最后是換行符,則換行符替換為空字符独柑。

??? 注意:cin對象給string對象賦值的時候會忽略回車符迈窟,但是不丟棄回車符,也就是說回車符依然存在與緩沖隊列中忌栅,如果此時后面跟的是getline函數(shù)车酣,那么很可能就會讀到一個空行(只有回車的行)。

??? get( )的成員函數(shù)索绪,該函數(shù)有幾種變體湖员。其中一種變體的工作方式與getline( )類似, 它們接受的參數(shù)相同瑞驱,解釋參數(shù)的方式也相同娘摔,并且都讀取到行尾。但get不再讀取并丟棄換行符唤反,而是將其留在輸入隊列中凳寺。如果沒有其它幫助,get()的這種用法將不能跨過換行符彤侍。使用函數(shù)cin.get(name,size)肠缨;接著跟一個cin.get();就可以吃掉換行符,效果與cin.getline(name,size)讀取并丟掉換行符的效果一樣盏阶。上面的cin.get()函數(shù)通過不同參數(shù)類型及數(shù)目晒奕,調(diào)用的函數(shù)的效果也不相同,這就是函數(shù)的重載般哼,這在后面函數(shù)部分會再次看到吴汪。

??? getline( )使用起來簡單一些 ,但 get( )使得檢查錯誤更簡單些蒸眠,因為我們可以通過查看下一個字符是否為回車等方式來觀察字符數(shù)組是否將我們輸入的字符完全容納可以用其中的任何一個來讀取一行輸入:只是應(yīng)該知道杆融,它們的行為稍有不同楞卡。

(3)空行和超過字符數(shù)時候的處理方式:

??? 當(dāng) get( ) (不是getline())讀取空行(空行不是空白行,空行指的是只有回車的行,一般是在用cin或cin.get(str,10)讀取一行后留下的回車符)后將設(shè)置失效位( failbit)蒋腮。這意味著接下來的輸入將被阻斷淘捡,可以使用命令cin.clear()來使阻斷的輸入繼續(xù)。(這里其實可以通過每次查看標(biāo)志位來查看發(fā)生了什么池摧,比如if(cin.rdstate() == ios::failbit))或者cin.eof(),cin.fail(),cin.bad()等方式焦除,然后來確定下一步如何做,一般在循環(huán)語句的時候使用)作彤。

??? 1炱恰!=呋洹4雌稀!輸入字符串可能比分配的空間長 則getline( )和 get( )將把余下的字符留在輸入隊列中绢慢,而 getline( )還會設(shè)置失效位灿渴,并關(guān)閉后面的輸入,也就是跳過后面的所有的輸入語句胰舆,直到用cin.clear()來恢復(fù)阻斷位骚露。get()函數(shù)不會這樣,它只是將余下的字符當(dāng)成下一行的開頭缚窿,由下面的輸入語句繼續(xù)輸入(直到回車或達(dá)到字符數(shù)限制)棘幸。所以,使用getline我們只需要查看阻斷位就可以判斷是不是數(shù)組容量不夠滨攻,然后進(jìn)行處理够话,并且不會破壞輸入的內(nèi)容;而對于get我們要使用cin.get()來查看下一個字符是不是回車來判斷是否字符數(shù)組容量不夠光绕,如果不是回車的話女嘲,cin.get()本身會吃掉一個字符,造成內(nèi)容的破壞(可以使用cin.peek()來不破壞地查看)诞帐。

(4)綜合以上的考慮欣尼,cin對象的輸入并不是特別好用,cin本身不能跨越空格停蕉;而cin.getline()和cin.get()都是以行為輸入對象愕鼓,而這兩者又所不同,cin.getline()會吃掉回車慧起,并且不能全部容納整行的時候會設(shè)置失效位菇晃;cin.get()則不會去掉回車,并且讀取空行之后會設(shè)置失效標(biāo)志位蚓挤。也就是說磺送,cin忽略空白驻子,只輸入一個單詞;cin.get();不會丟掉換行符估灿,并且有空行的時候會阻斷崇呵;而cin.getline();會丟掉換行符,是面向行來輸入的馅袁,只有行太長的時候會阻斷域慷。即,有空白行汗销,使用get要注意犹褒,有太長的行,使用getline要注意大溜。如果是使用string對象的話化漆,因為不用考慮長度問題,因此使用cin.getline是沒有任何缺點的钦奋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末座云,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子付材,更是在濱河造成了極大的恐慌朦拖,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厌衔,死亡現(xiàn)場離奇詭異璧帝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)富寿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門睬隶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人页徐,你說我怎么就攤上這事苏潜。” “怎么了变勇?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵恤左,是天一觀的道長。 經(jīng)常有香客問我搀绣,道長飞袋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任链患,我火速辦了婚禮巧鸭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘麻捻。我一直安慰自己蹄皱,他們只是感情好览闰,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布芯肤。 她就那樣靜靜地躺著巷折,像睡著了一般。 火紅的嫁衣襯著肌膚如雪崖咨。 梳的紋絲不亂的頭發(fā)上锻拘,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音击蹲,去河邊找鬼署拟。 笑死,一個胖子當(dāng)著我的面吹牛歌豺,可吹牛的內(nèi)容都是我干的推穷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼类咧,長吁一口氣:“原來是場噩夢啊……” “哼馒铃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起痕惋,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤区宇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后值戳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體议谷,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年堕虹,在試婚紗的時候發(fā)現(xiàn)自己被綠了卧晓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡赴捞,死狀恐怖逼裆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情螟炫,我是刑警寧澤波附,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站昼钻,受9級特大地震影響掸屡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜然评,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一仅财、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碗淌,春花似錦盏求、人聲如沸抖锥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽磅废。三九已至,卻和暖如春荆烈,著一層夾襖步出監(jiān)牢的瞬間拯勉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工憔购, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留宫峦,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓玫鸟,卻偏偏與公主長得像导绷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子屎飘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354