cin的用法及清空輸入緩衝區問題

2021-06-22 14:29:49 字數 2185 閱讀 8734

問題描述:輸入資料時希望有個合法性檢驗的問題,如果輸入的資料不合法則程式提示重新輸入。最初**如下:

#include

#include

using std::cin ;

using std::cout ;

using std::endl;

using std::vector ;

int main()

while(ivec.size()==0);

//其他語句}

這樣寫如果第一次正確輸入,程式執行正確。但如果第一次沒有輸入有效字元(比如輸入ctrl+z,回車)或者第乙個輸入為非法字元,則程式陷入死迴圈,不停的輸出提示資訊,但是不允許使用者再次輸入。

正確寫法:

#include

#include

using std::cin ;

using std::cout ;

using std::endl;

using std::vector ;

int main()

while(ivec.size()==0);}

增加上面兩行之後,可以實現預定功能,程式執行正常。

說明原因:

首先需要了解cin的用法。程式的輸入都有乙個緩衝區,當一次鍵盤輸入結束時會將輸入的資料存入輸入緩衝區,而cin函式直接從輸入緩衝區中讀取資料。這種緩衝機制規定,只有收到回車鍵時,才會將所有輸入的資料一次性提交到cin函式。回車標誌一次輸入的完成,如果資料不夠,則會等待使用者繼續輸入;如果資料有多餘,則將多餘的資料儲存在輸入流緩衝區中,供下次使用。舉個栗子:

while(cin>>num)

cout<

這條語句,如果輸入一次1   2   3   4 ,執行結果是: 1

2 34

執行過程如下:

第一次執行cin>>num的時候,輸入緩衝區為空,所以會顯示下劃線讓使用者輸入。使用者輸入1  2  3  4  ctrl+z,回車,這時候cin讀入第乙個整數1,然後輸出1和換行。

下一次執行 cin>>num的時候,緩衝區不為空,所以不再要求使用者輸入,直接讀取第二個整數2,然後輸出2和換行。以此類推,依次輸出3 ,4。

然後cin檢查到結束標誌ctrl+z,cin>>num返回false,迴圈退出。

需要特別注意的一點是:當緩衝區中有殘留資料時,cin函式會直接去讀取這些殘留資料而不會請求鍵盤輸入。而且,回車符也會被存入輸入緩衝區中。

有了這些知識,就可以解釋原始**中的現象了。如果第一次沒有輸入有效字元,以ctrl+z加上回車鍵結束輸入後,回車符會被當成乙個字元存入輸入緩衝區。下一次再執行時,到了while(cin>>num)這一步,由於緩衝區中已有乙個回車符,所以cin函式直接去緩衝區中讀取回車符,而不允許使用者再次輸入資料,這就是第一次非法輸入後不能再次輸入資料的原因。由於需要的資料num是int型的,顯然讀取到的回車符仍然是非法的,程式再次進入下乙個迴圈,並且一直這樣迴圈下去,這就是程式陷入死迴圈原因。

解決辦法:

從上面的分析我們可以看出,導致問題的根本是輸入緩衝區沒有及時清空,以至於前一次的輸入影響了後面的輸入。因此,在輸入前加上清空輸入緩衝區的語句就可以解決問題。c++用於清空輸入快取的函式有三個:cin.clear(),cin.sync(),cin.ignore()。

cin.clear()是用來更改cin的狀態標示符的,cin在接收到錯誤的輸入的時候,會設定狀態位good。如果good位不為1,則cin不接受輸入,直接跳過。如果下次輸入前狀態位沒有改變那麼即使清除了緩衝區資料流也無法輸入。所以清除緩衝區之前必須要cin.clear()。

cin.ignore(a,ch):從輸入緩衝去中提取字元,提取的字元被忽略,不被使用。每拋棄乙個字元,它都要計數和比較字元,如果計數值達到a或者被忽略的字元是ch,則cin.ignore()函式終止執行。預設引數是a=1,即僅忽略緩衝區中的第乙個字元。它的乙個常用功能是用來清除以回車結束的輸入緩衝區的內容,消除上一次輸入對下一次輸入的影響。比如cin.ignore(1024,'\n'),

通常把第乙個引數設定得足夠大,這樣實際上總是只有第二個引數起作用,所以這一句就是把回車(包括回車)之前的所有字元從輸入緩衝區中清除。

cin.sync()的作用是清除輸入緩衝區全部的內容。

另外,函式fflush(stdin)的功能也是清空輸入緩衝區,但是此函式並不是在c/c++標準中定義的,它僅適用於部分編譯器(如vc),並非所有的編譯器都支援這個功能。經過實驗,在visual studio中用這個函式無法清空輸入緩衝區。

cin的用法及清空輸入緩衝區問題

include include using std cin using std cout using std endl using std vector int main while ivec.size 0 其他語句 這樣寫如果第一次正確輸入,程式執行正確。但如果第一次沒有輸入有效字元 比如輸入ct...

清空輸入緩衝區

清空輸入緩衝區 cin.clear 清除錯誤標記,比如要求輸入int型,但我們輸入了char型,就會導致輸入錯誤,產生錯誤標記 cin.sync 清空輸入緩衝區 cin.ignore n,ch 第乙個引數是清空輸入緩衝區的大小,第二個引數是終止字元 注 終止字元也會被丟棄 常用形式有以下兩種 cin...

清理cin輸入緩衝區 在C 中清除輸入緩衝區

問題引入 用過c 的都明白,在運用輸入過程中會出現不經意間意外輸入錯誤的情況,導致之後的輸入無效,c 內部會繼續使用之前的意外輸入,使得程式執行錯誤。輸入緩衝區 所有從鍵盤輸入的資料,不管是字元還是數字,都是先儲存在記憶體中的乙個緩衝區裡面,叫做鍵盤緩衝區,簡稱輸入緩衝區或者輸入流。當一次鍵盤輸入結...