為什麼 while (getline(cin, s)) 跳出循環後 s 的值為空?
01-05
今天看c++primer時候發現一個問題,就是書中78頁中getline那裡,
書里使用while(getline(cin, line))這樣循環輸入一行的,就再這頁的上面while(cin &>&> word),這個循環中可以用ctrl+z或者ctrl+d退出循環,繼續執行下面的代碼,但是同用到while(getline(cin, line))中就不行了。例如書上:
void main()
{
string s;
while (getline(cin, s))
cout &<&< s &<&< endl; system("pause"); }輸出:
hello world
hello world^Z請按任意鍵繼續……修改後:
void main()
{
string s;
while (getline(cin, s));
cout &<&< s &<&< endl; system("pause"); }輸出:
無論 Windows 還是 Linux,這個 s 都沒有接收到輸入的「hello world」,請問這是為什麼?hello world
^Z
請按任意鍵繼續……
因為回車輸入的是一個換行符,相當於另起一行,所以getline()會把這個空行讀到s裡面去,你最後輸出的當然就是一個空行。
但是,要理解這個過程究竟是怎麼發生的,題主應該要明白幾個概念:(1)eof標誌(2)cin的狀態while(geline(cin,s))這個語句的執行過程是這樣的:先調用getline()函數,getline()將istream cin中的內容讀取一行(你輸入的是hello world),保存進string s中,而getline()的返回值就是cin。也就是說,這個循環的判定條件是while(cin),cin是怎麼轉化為bool類型進行條件判斷的呢?這個判定實際上隱式調用了 !cin.fail(),而fail()這個成員函數被定義在ios_base類裡面(這是istream的基類basic_ios的基類)。
那麼調用fail()返回的是什麼?是cin的狀態。cin的狀態是由4個標誌位指示的(關於stream的標誌的內容實際上就可以在C++ Primer中找到),分別是badbit(表示流已經崩潰),failbit(表示IO操作失敗),eofbit,goodbit。當badbit或者failbit被置位時,fail()會返回true,!fail()結果為false。當遇到文件末端時,eofbit和failbit都會被置位,因此只有碰到Ctrl+Z(Windows下輸入即等同文件末端eof),while()條件不再滿足,退出。再來看你的操作過程,hello world,回車,Ctrl+Z。所以程序最後這麼運行的:hello world被讀入s,換行後的空行被讀入s,末端標誌eof使cin為無效狀態,while()判斷為假,循環退出。輸出s。以上。接收到了,但是後來又被一個空行覆蓋掉了。所以輸出了個空行。
你的錯誤是while語句後面多了個分號,所以一直在while循環,根本沒執行後面的cout和system("pause")。明白了?界面停在那裡,不是因為pause,而是因為死循環。
你程序一開始輸出的hello world不是cout出來的,是輸入時的回顯而已。
windows 下不清楚
linux 下 ctrl +d 是 eof+z,+c 都是發信號幹掉你的進程測試程序如下clang++ http://main.cc ./a.out在OSX 10.10下ctrl + z echo $? 130ctrl + cecho $? 147
ctrl + decho $? 0 #include &
#include &
using namespace std;
int main() {
string s;
while(cin &>&> s)
;
}
推薦閱讀: