首先注意:
1、每一個輸入(輸出)對象就代表一個輸入(輸出)流;
2、輸入(輸出)對象中的流狀態成員標記了輸入(輸出)流當前的狀況,當eofbit、badbit、failbit三個標記位均為0時表示流狀態正常;
3、一但某個或幾個標記位被設置,表示對象的流狀態出現相應狀況,流將對后面的輸入(輸出)關閉,直到標記位被清除;
4、只有在流狀態良好的情況下,if或者while對該輸入(輸出)對象的判斷才能是ture。
接下來看看這個程序:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int input; 7 while (cin >> input) 8 { 9 cout << input << endl; 10 cout << "rdstate()函數的返回值: " << cin.rdstate() << endl; 11 cout << "三個標記位返回的返回值: " << cin.bad() << cin.fail() << cin.eof() << endl; 12 cout << "goodbit標記位的返回值: " << cin.good() << endl; 13 cout << endl; 14 } 15 16 cout << "rdstate()函數的返回值: " << cin.rdstate() << endl; 17 cout << "三個標記位返回的返回值: " << cin.bad() << cin.fail() << cin.eof() << endl; 18 cout << "goodbit標記位的返回值: " << cin.good() << endl; 19 20 if (!cin) 21 cout << "input error" << endl; 22 23 else 24 cout << input << endl; 25 26 system ("pause"); 27 return 0; 28 }
當輸入為:“123 124 158 137a”時,輸出為:
具體分析如下:
123、124、158均被正常抽取,從rdstate()等 流狀態標記位測試函數的返回結果可以看出來。
當輪到137a進入程序時,抽取操作符將137成功抽取,將a留在輸入流中。抽取操作符“ >> ”返回cin對象,此時流狀態仍為正常,failbit、eofbit、badbit三個標記位的值均為0。然后while判定cin對象為true,使得進入循環輸出137及流狀態信息。
接下來進入下一次循環,執行 cin >> input ; 語句:a為輸入流的第一個字符,a與input變量類型不匹配,導致cin流狀態的failbit標記位被置為1(goodbit標記位被置為0),這使得“ >> ”返回的cin對象自身檢測為False, 然后while判定cin對象為false,退出循環。而字符a,留在了輸入流中。
退出循環后輸出cin的流狀態,可以看出,rdstate()的結果是4,failbit標記位為1,goodbit標記位為0。
程序流程到了 if 語句,此時cin對象的failbit標記位已經被置為1(goodbit標記位被置0),if 判定cin對象為false ,那么 !cin 為true,因此輸出input error。
當輸入文件結束符(^Z,即Ctrl+Z 或 F6)時,輸出為:
badbit 標志着系統級的故障,如無法恢復的讀寫錯誤。如果出現了這類錯誤,則該流通常就不能再繼續使用了。如果出現的是可恢復的錯誤,如在希望獲得數值型數據時輸入了字符,此時則設置 failbit 標志,這種導致設置 failbit的問題通常是可以修正的。eofbit 是在遇到文件結束符時設置的,此時同時還設置了 failbit。
流的狀態由 bad、fail、eof 和 good 操作提示。如果 bad、fail 或者 eof中的任意一個為 true,則檢查流本身將顯示該流處於錯誤狀態。類似地,如果這三個條件沒有一個為 true,則 good 操作將返回 true。
再來看一看下一段代碼:
1 if (cin >> input) 2 cout << input << endl; 3 else 4 cout << "input error" << endl; 5 6 if (!cin) 7 cout << "input error" << endl; 8 else 9 cout << input << endl;
當輸入為567a時,輸出為:
567
567
原因:輸入流中的567被“ >> ”抽取到 input 中,因此抽取操作符“ >> ”返回的cin對象的流狀態成員正常。因此 !cin 為false,使得再一次輸出567。注意:字符a留在了輸入流。
但當代碼重復一次時:
1 if (cin >> input) 2 cout << input << endl; 3 else 4 cout << "input error" << endl; 5 6 if (!cin) 7 cout << "input error" << endl; 8 else 9 cout << input << endl; 10 //第一次代碼結束 11 12 if (cin >> input) 13 cout << input << endl; 14 else 15 cout << "input error" << endl; 16 17 if (!cin) 18 cout << "input error" << endl; 19 else 20 cout << input << endl; 21 //重復代碼結束
如果輸入567a,輸出是:
567
567
input error
input error
原因是:當第一次代碼正常完成后, 第二次代碼開始,輸入流中的第一個字符是a,a與input不匹配,“ >> ”無法抽取, 抽取操作符“ >> ”函數返回的cin對象,其failbit標記位被置為1(goodbit標記位被置為0) ,cin的自測為False,if 判定條件為false;且導致下一個if語句: if (!cin) 中, cin對象為false, !cin 為true。
真相是:只要抽取操作符“ >> ”能成功抽取輸入流中的數據,哪怕只是部分匹配,cin對象的流狀態成員(即標記位)不會被設置,流狀態仍將保持正常。
一旦輸入完全不匹配,“ >> ”無法進行任何抽取,返回的cin對象其failbit標記位置為1(goodbit標記位被置0),cin流狀態出現相應狀況 ,且在恢復之前,流將對后面的輸入關閉。
不對之處,敬請指教。
參考文獻:http://blog.csdn.net/ygj149078299/article/details/538998