#include <stdexcept> //runtime_error在其中定義
using namespace std;
int main(){
int ival;
while(cin>> ival,!cin.eof()){
if (cin.bad())
throw runtime_error("IO stream corrupted");
if (cin.fail()){
cerr << "bad data ,try again";
cin.clear(istream::failbit);
continue ;
}
}
return 0;
}
我輸入 w 後 流處於錯狀態, cin.clear(istream::failbit)語句清理輸入 流 的 錯誤信息,使流重新有校,但是程序運行時卻是一直錯誤,那是因爲錯誤字符w一直在緩衝區中,並沒有被清除 ,cin每次從緩衝區中讀入錯誤信息 ,即使流狀態糾正,下次讀取還會出錯,所以程序運行時一直在錯誤的死循環中,但是加了兩個getchar()後就好了:
#include <iostream>
#include <stdexcept> //runtime_error在其中定義
using namespace std;
int main(){
int ival;
while(cin>> ival,!cin.eof()){
if (cin.bad())
throw runtime_error("IO stream corrupted");
if (cin.fail()){
cerr << "bad data ,try again";
getchar();
getchar();
cin.clear(istream::failbit);
continue ;
}
}
return 0;
}
第一個getchar()用於清空輸入緩衝區中的錯誤字符w,第二個getchar()用於清空輸入緩衝區中的回車符'\n' (在輸入完w後,按的回車),這樣輸入緩衝區就能被清空,但是如果只有用一個getchar()也能解決問題,那一個getchar()和兩個getchar()有什麼區別?
用一個getchar(),那麼輸入緩衝區中還會剩下一個回車符,那時流已經處於正常狀態,但是cin有個特性,他會忽略前導回車符,就是cin從緩衝區中讀取數據時,如果緩衝區開頭是回車符'\n'
那麼cin會忽略,無論有多少個回車符,只要在緩衝區開頭且連續,cin都會忽略。所以用一個getchar()也能解決問題;
如果不用getchar(),用cin.ignore(1,' '),也能解決問題(原理和一個getchar()類似),但是cin.ignore(1,' ')必須放對位置,如果放在cin.clear(istream::failbit)前是沒有用的,必須放在cin.clear(istream:failbit)後面,因爲放在前面的話,那時後流還處於 錯誤狀態,cin.ignore(1,' ')不會有作用,必須在流處於正確狀態纔有用。