近幾天在學cin流對象的成員函數,在看到cin.sync();時發現網上很多博客中的用法在本地的環境無法實現(VS2017)
比如如下代碼:
#include<iostream> using namespace std; int main() { int a; while (1) { cin >> a; if (cin.rdstate()) //條件可改寫為cin.fail() { cout << "輸入有錯!請重新輸入" << endl; cout << cin.rdstate() << endl; cin.clear(); cin.sync();//cin.ignore(std::numeric_limits<int>::max(),'\n'); cout << cin.rdstate() << endl; } else { cout << a; break; } } system("pause"); }
運行結果如下,陷入死循環

而按網上許多人寫的博客里的說法,cin.sync();應該是清空緩存區的意思
為此我換了G++來重新測試代碼
得到結果是如下:

等待輸入,按照G++的運行結果來看,cin.sync();又確實是清空緩沖區的功能
那么為什么在不同的編譯環境下,函數的功能不一樣呢?
我去查詢了資料
http://www.cplusplus.com/forum/general/63860/
額,,,,學好英語是必要的
大致意思就是對於 std::cin 這些標准庫「自帶」的輸入流來說,調用 sync() 是「實現定義」的行為
所以此處調了 sync() 以后清空、恢復原狀、什么都不干都是可以的,如果沒有得到預期的效果的話,可以查看自己的編譯器(標准庫實現)的說明文檔,上面應該有寫明它所使用的是哪種行為。
具體可以參考:cppreference.com
總之對這個誤解的人還蠻多的,因為不少編譯器里確實定義的是清空的行為(可sync明明是同步的意思啊喂,所以定義成和數據源同步的操作才會更舒服好吧)
解決方法呢,就是用cin.ignore();
cin.ignore(std::numeric_limits<int>::max(),'\n');
把第一個參數設置得足夠大,這樣實際上總是只有第二個參數'\n'起作用,所以這一句就是把回車(包括回車)之前的所以字符從輸入緩沖(流)中清除出去,用此來達到清空數據流的操作;
這樣就能吃掉一大段了,但理論上依舊不能保證吃掉一行
所以還是一次吃一個好了
cin.ignore(1,EOF);

