2017-07-12 42 views
0

我正在學習C++ Primer第4版,並正在使用IO流。當我試圖運行書中的代碼(頁289):詢問和控制流的狀態

#include <iostream> 
#include <string> 
using namespace std; 
int main() 
{ 
    int ival; 
    // read cin and test only for EOF; loop is executed even if there are 
    // other IO failures 
    while (cin >> ival, !cin.eof()){ 
     if (cin.bad()) // input stream is corrupted; bail out 
      throw runtime_error("IO stream corrupted"); 
     if (cin.fail()){ 
      cerr << "bad data, try again\n"; 
      cin.clear(istream::failbit); 
      continue; 
     } 
     //ok to process ival 
    } 
} 

我輸入一個字符串(說「是」)後,遇到了一個無限循環。那麼這個代碼有什麼問題?

+0

你說「C++ Primer第4版」。請通過提供一個作者姓名(&理想的是一個ISBN)來消除歧義 –

回答

0

輸入字符串時,提取到ival失敗,並且失敗位被設置。然後,你盡忠職守地嘗試清除這個位並繼續。但是那個字符串仍然在緩衝區中!所以這個行爲永遠重演。

此外,you didn't actually clear the bit; you just set the stream state to failbit

你需要打電話只是std::cin.clear(),然後從緩衝器拉出意外的數據,然後再繼續。

此外, while (cin >> ival, !cin.eof())是奇數;我沒有檢查行爲或優先順序,但我想你只會寫 while ((cin >> ival) && !cin.eof())

總之,如果這是真的在書中的代碼,你需要一個更好的書,因爲代碼是錯誤的一些嚴重的方式。如果你真的編程C++ 14,那麼你需要一本更新的書,因爲Lippman的C++ Primer在C++ 11之前甚至沒有更新,直到第5版。

+0

我只是嘗試用cin.clear()替換cin.clear(istream :: failbit),但它仍然不起作用。那麼我怎樣才能清除緩衝區?我知道這本書很古老,但它仍然有幫助。對於逗號的事情,我認爲「a,b」是返回b的表達式。 –

+0

@GuojunZhang:是啊,你所要做的_everything_我說,不只是它的一部分 –

+0

@GuojunZhang:是的,'一,B'計算結果爲'B',但'一<< B,C'可能不會做什麼你期待;取決於'<<'和','之間的關係。我沒有時間檢查現在,我最喜歡的表情檢查工具已離線:((geordi --precedence ') –

0

最後使它通過添加cin.ignore(INT_MAX, '\ n')工作。此行是必需的,因爲cin.clear()僅在數據保留在緩衝區中時刪除錯誤標誌。爲了清除緩衝區cin.ignore是必要的。

#include <iostream> 
#include <string> 
using namespace std; 
int main() 
{ 
    int ival; 
    // read cin and test only for EOF; loop is executed even if there are 
    // other IO failures 
    while (cin >> ival, (!cin.eof())){ 
     if (cin.bad()) // input stream is corrupted; bail out 
      throw runtime_error("IO stream corrupted"); 
     if (cin.fail()){ 
      cerr << "bad data, try again" << endl; 
      cin.clear(); 
      cin.ignore(INT_MAX, '\n'); 
     } 
     //ok to process ival 
    } 
}