cin是使用空白(空格,制表符,換行符)來确定字元串的結束位置這意味着cin在擷取字元數組時隻讀取一個單詞。讀取該單詞後cin自動在其結尾增加空字元。
這有時候很友善,有時候有使我們煩惱:如果我要輸入一句話來存入字元串中呢?
要将整條短語而不是一個單詞作為字元串輸入,需要采用另一種字元串讀取方法。
具體地說,需要采用面向行而不是面向單詞的方法。
istream的類cin提供了一些面向行的類成員函數:getline() and get()
這兩個函數都讀取一行輸入,直到遇到換行符為止。
不同的是getline()随後将丢棄換行符,而get()将換行符保留在輸入序列中。
下面先說說getline():
geiline的使用方法是cin.getline(char*, int)。
該函數有兩個參數,第一個是你要儲存的目标,第二個是最多讀取多少位字元。如,若該參數為29,則最多讀取28個字元。餘下的空間是留給空字元的。
getline成員函數在讀取指定字元數或者遇到換行符時停止讀取。
注意,可以認為getline()讀取換行符,但随後将換行符丢棄,換成空字元。
關于get():
get成員函數有多重變體,其中有一種與getline相似,他們接受的參數個數相同,參數的解釋也相同,并且都讀取到行尾。
值得注意的是,get函數并不讀取并丢棄換行符,而是将其留在輸入序列中。這種特點如果不留意的話,會造成一些難以預料的麻煩。
下面舉個栗子,當我們連續兩次使用get():
cin.get(name, size);
cin.get(hobby, size);
第一次調用get()時,将換行符留在輸入隊列中,是以第二次調用時看到的第一個字元便是換行符,是以第二個get函數會認為已經到達行尾,便不再讀取以下内容。
這個時候我們需要借助get函數的另一種變體,即不帶任何參數的get函數:cin.get(),它可以讀取下一個字元,即使是換行符,是以可以用它來處理換行符。
它的調用形式可以是以下兩種:
//第一種:
cin.get(name, size);
cin.get();
cin.get(hobby, size);
cin.get();
//第二種:
cin.get(name, size).get();//之是以可以這樣做,是因為cin.get(name, size)傳回一個cin對象,
//這個對象随後被用來通路get成員函數。
cin.get(hobby, size).get();
More:在使用cin之後使用getline的情況,如:
int year;
char name[];
cin >> year;
cin.getline(name, );
這種情況下name中儲存的不是我們輸入進去的字元串,而是空字元串。原因是cin在讀取year之後将換行符留在了輸入隊列,getline一開始就遇到換行符。
而我們以前連續調用cin不會産生讀取空字元串的情況,是因為cin會自動忽略掉開頭的換行符。
另外再做一下說明:
getline(char*, int)成員函數和get(char*, int)成員函數不适合于C++的string類。
或者這麼說,适用于string類的getline函數并不是istream的成員函數,而是其友元函數,是以如果要讀取一行字元串到string對象中,需要使用下面的格式:
getline(cin, str);
而get函數不适合于string類對象。
為什麼string類的對象搞特殊呢?這是曆史原因啦。
關于cin.get()函數的補充:
get()函數還有兩種變體
一種是接受一個char類型作為參數:
cin.get(ch);
該函數傳回一個cin對象。
由于cin在需要的情況下可以轉為bool值,是以可以用cin.get(ch)函數來判斷輸入是否到達結尾:
cin.get(ch);
while (cin) {
……
cout << ch;
cin.get(ch);
}
//或者采用更簡潔的表示:
while (cin.get(ch)) {
cout << ch;
}
P.S.這裡的“輸入到達結尾”是指從鍵盤模拟的EOF,Windows下是Ctrl + z + Enter
另一種是
該函數不接受任何參數,它的作用是讀取下一個字元并指派給ch。
當然這個表達式的值是指派運算符左邊的值,即ch;
是以這個函數也可以用來判斷輸入是否到達結尾:
while (ch != EOF) {
cout << ch;
ch = cin.get();
}
//或者采用更簡潔的表示:
while ((ch = cin.get()) != EOF) { //這個表達式的值是指派運算符左邊的值,即ch;
cout << ch;
}
在希望逐位元組地讀取文本檔案或文本輸入時,可以使用這兩個函數。
為什麼不是cin >> ? 因為cin将自動地忽略空格,換行符,制表符,有時候,我們并不期待這種事情的發生。
下面是這兩個函數的差別:
屬性 | cin.get(ch) | ch = cin.get() |
---|---|---|
傳遞輸入字元的方式 | 賦給參數ch | 将函數傳回值賦給ch |
用于字元輸入時函數的傳回值 | istream對象(執行bool轉換後為true) | int類型的字元編碼 |
到達EOF時函數的傳回值 | istream對象(執行bool轉換後為false) | EOF |
另外,cin.get(ch)還有一個好處就是它可以拼接起來,如:
cin.get(ch1).get(ch2);
最後,指出下列cin成員函數也可以判斷輸入是否到達結尾:
cin.fail()
cin.eof()