關於cin
cin是istream類的對象,它是從標準輸入設備(鍵盤)獲取數據,(此外,cout是流的對象,即ostream類的對象,cerr是標準錯誤輸出流的對象,也是ostream 類的對象。這裏的標準輸出和標準錯誤輸出指的是終端的屏幕) 程序中的變量經過流提取符">>"從流中提取數據。流提取符">>"從流中提取數據時跳過輸入流中的空格、tab鍵、換行符等空白字符。注意:只有在輸入完數據再按回車鍵後,該行數據才被送入鍵盤緩存區,造成輸入流,提取運算符">>"才能從中提取數據。須要注意保證從流中讀取數據能正常運行。
ios
例如: int a,b; cin>>a>>b;
若從鍵盤中輸入21 abc回車,變量a從輸入流中提取整數21,提取操做成功,此時cin流出於正常狀態。但在變量b準備提取一個整數時,遇到了字母a,顯然提取操做失敗了,此時,cin流被置爲出錯狀態。只有在正常狀態,才能從輸入流中提取數據。windows
字符輸入的流成員函數
除了能夠用cin輸入標準類型的數據外,還能夠用istream類流對象的一些成員函數,實現字符的輸入。如cin.get(),cin.getline(字符數組(或字符指針),字符個數n,終止標誌字符)數組
eof函數
eof是end of file 的縮寫,表示「文件結束」。從輸入流讀取數據,若是到達文件末尾(遇到文件結束符),eof函數值爲非零值(表示真),不然爲0(表示假)。緩存
peek函數
peek是觀察的意思,peek函數的做用是觀測下一個字符。 調用形式爲c=cin.peek();函數
putback函數
調用形式爲cin.putback(ch) 其做用是將前面用get或者getline函數從輸入流中讀取的字符ch返回到輸入流,插入到當前指針的位置,供後面讀取。spa
ignore函數
調用形式爲cin.ignore(n,終止字符) 函數做用是跳過輸入流中n個字符,或在遇到指定的終止字符時提早結束(此時跳過包括終止字符在內的若干字符)。指針
cin的狀態標示符:code
常量對象 |
含義blog |
failbit標記位的值 |
eofbit標記位的值 |
badbit標記位的值 |
轉化爲10進制 |
ios::failbit |
輸入(輸出)流出現非致命錯誤,可挽回 |
1 |
0 |
0 |
4 |
ios::badbit |
輸入(輸出)流出現致命錯誤,不可挽回 |
0 |
0 |
1 |
2 |
ios::eofbit |
已經到達文件尾 |
0 |
1 |
0 |
1 |
ios::goodbit |
流狀態徹底正常 |
0 |
0 |
0 |
0 |
分別對應cin.fail(),cin.bad(),cin.eof(),cin.good()
cin.rdstate()對應十進制。
while(cin>>n)
最近在看C++,學到了標準庫這一章,看到cin的時候,咱們常常看到不少的代碼中會有這麼一段while(cin>>x){ ......}。這裏咱們最關注的問題是while括號裏面cin>>x他每次輸入的時候返回的是什麼值呢。因此咱們也就會問cin的返回值是什麼。我也看到不少像我這樣的新手問這樣的問題,下面說下我我的的看法,若有不當之處,還請指正!
其實我倒以爲咱們這個問題問錯了,咱們不該該問cin返回值是什麼,我以爲咱們應該關注">>"輸入操做符,實際上是它到底返回了什麼。由於cin是標準輸入istream的一個對象,一個對象能返回什麼嗎?對象有返回值嗎?好像沒有吧!在C++primer裏面講到過,cin>>x>>y。有這麼一行代碼,咱們討論下">>"這個輸入操做符,這個操做符接收一個istream對象做爲其作操做數,接收一個對象做爲其右操做數。">>"操做符返回其左操做數做爲結果,這樣也就能夠解釋爲何上面能夠將兩個輸入操做合併了。由於cin>>x返回cin對象,接着又能夠進行cin>>y。因此咱們就能夠順利進行輸入了。因此咱們再來看上面的那個while循環,裏面的cin>>x,返回的是cin對象(注意是輸入操做符「>>」返回),因此返回的也就能夠認爲是流自己了。咱們再來看下他何時退出循環。由於咱們已經知道了括號裏面的返回值了,因此咱們看看它何時退出循環。
輸入(cin)緩衝是行緩衝。當從鍵盤上輸入一串字符並按回車後,這些字符會首先被送到輸入緩衝區中存儲。每當按下回車鍵後,cin 就會檢測輸入緩衝區中是否有了可讀的數據,這種狀況下cin對鍵盤上是否有做爲流結束標誌CTRL+Z或者CTRL+D,其檢查的方式有兩種:阻塞式以及非阻塞式。這裏借用一點網上搜到的資料,
阻塞式檢查方式指的是隻有在回車鍵按下以後纔對此前是否有 Ctrl+Z 組合鍵按下進行檢查,非阻塞式樣指的是按下 Ctrl+D 以後當即響應的方式。若是在按 Ctrl+D 以前已經從鍵盤輸入了字符,則 Ctrl+D的做用就至關於回車,即把這些字符送到輸入緩衝區供讀取使用,此時Ctrl+D再也不起流結束符的做用。若是按 Ctrl+D 以前沒有任何鍵盤輸入,則 Ctrl+D 就是流結束的信號。
阻塞式的方式有一個特色:只有按下回車以後纔有可能檢測在此以前是否有Ctrl+Z按下。還有一個特色, Windows下是不用CTRL+D的,若是在你的程序中使用CTRL+D的話,若是你還有要輸入的數據的話,會直接掛掉的,不能再輸入了。Windows下是使用CTRL+Z的。 在你輸入CTRL+Z後,括號裏面的數據變爲0了。來看一段程序:(vc6.0上運行)
#include <iostream> using namespace std; int main(void) { int i; cout<<(cin>>i)<<endl; return 0; }
當你按下CTRL+Z後,按下兩次回車,就能夠獲得結果0.因此上面的while會退出循環。可是當你在你的程序中輸入數據的時候,你要結束輸入,你輸完數據直接回車,再按下CTRL+Z,再按下回車就能夠結束了。由於前面說過若是輸入緩衝區中有可讀的數據則不會檢測 Ctrl+Z(由於有要讀的數據,還不能認爲到了流的末尾)。還有一點須要知道,Ctrl+Z產生的不是一個普通的ASCII碼值,也就是說它產生的不是一個字符,因此不會跟其它從鍵盤上輸入的字符同樣可以存放在輸入緩衝區。!
在理解cin功能時,不得不提標準輸入緩衝區。當咱們從鍵盤輸入字符串的時候須要敲一下回車鍵纔可以將這個字符串送入到緩衝區中,那麼敲入的這個回車鍵(\r)會被轉換爲一個換行符\n,這個換行符\n也會被存儲在cin的緩衝區中而且被當成一個字符來計算!好比咱們在鍵盤上敲下了123456這個字符串,而後敲一下回車鍵(\r)將這個字符串送入了緩衝區中,那麼此時緩衝區中的字節個數是7 ,而不是6。
cin讀取數據也是從緩衝區中獲取數據,緩衝區爲空時,cin的成員函數會阻塞等待數據的到來,一旦緩衝區中有數據,就觸發cin的成員函數去讀取數據。當cin>>從緩衝區中讀取數據時,若緩衝區中第一個字符是空格、tab或換行這些分隔符時,cin>>會將其忽略並清除,繼續讀取下一個字符,若緩衝區爲空,則繼續等待。可是若是讀取成功,字符後面的分隔符是殘留在緩衝區的,cin>>不作處理。
使用一個istream的對象做爲條件時,效果是檢查流的狀態。若流有效,則檢測成功,返回true。當遇到文件結束符或者無效的輸入(好比用一個字符來做爲一個整型數的輸入時),istream的對象狀態會變爲無效。
總結:cin是一個istream的對象,判斷時會檢查流的狀態,流有效返回ture,當文件結束符或者無效的輸入(好比用一個字符來做爲一個整型數的輸入時)時,返回false。
注:windows環境下ctrl+z 結束輸入
ctrl+c直接結束數據(數據不會進去緩存區)
我的理解,有錯誤還望指出。