關於if (!cin)以及while (cin >> word)


首先注意:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM