話說剛才寫求最大公約數的代碼時,為了提高可靠性,加入了IO錯誤判斷,可測試結果讓人不解,先看修改前的部分代碼:
int a = 0, b = 0;
cout << "Please input two number to computing they GCD: ";
while (!(cin >> a >> b))
{
cin.clear(); // 將流中的所有狀態值都重設為有效值
cout << "Input Error !" << endl;
cout << "Input againt: " << endl;
}
// gcd 即 Greatest Common Divisor,最大公約數.
cout << "The GCD is " << gcd(a, b) << endl;
按理(從《C++ Primer》看來的)說,輸入錯誤時,進入了迴圈體,接著調用 clear 方法重設狀態值,然後 cin 流對象就處於正常狀態了,我們就可以重新輸入兩個數值以求最大公約數了。可事實是,進入迴圈體後,再也出不來了,一個勁兒地迴圈。
我調試呀調試,發現問題可能出在 clear 方法上,可是《C++ Primer》也是這麼用的呀!好吧,這是我的錯,我得先檢討一下再繼續往下講。為了趕進度,我在很短的時間裡把《C++ Primer》看了一遍,可這隻是粗略看一遍,書上的代碼基本上就沒有上機實踐過,我錯了,原諒我吧。
經過一番百度,發現原來是把 clear 的老情人 sync 給丟了。俗話說的好,男女搭配,幹活不累。沒了 sync,clear 自然就整天魂不守舍地徘徊不前,等待夢中情人的出現。好了,有請 sync 先生出場:
while (!(cin >> a >> b))
{
cin.sync(); // 清除輸入緩衝區中的資料流,功能與 fflush(stdin) 相同. cin.clear(); // 將流中的所有狀態值都重設為有效值.
cout << "Input Error !" << endl;
cout << "Input againt: " << endl;
}
恭喜 clear 女士脫離光棍行列,終於可以讓我們繼續輸入數值了。
分析一下,當我們輸入了錯誤的數值後,cin 對象處於錯誤狀態,代碼進入迴圈體,接著我們調用 clear 方法重設了 cin 對象的狀態。此時,cin 對象已經處於正確狀態了,但是有一點需要注意,這些狀態只是用來告訴別人,我 cin 已經沒有問題了。當然啦,神經病自己都會說自己沒病,有病不是說句話就能好的,有病還得治。打從 cin 裡塞進了垃圾資料之後,這些垃圾就沒清除掉。所以得讓 sync 把垃圾資料給清除掉,清除之後才可以再放有用的東西。OK,垃圾也清除了,狀態也正常了,活可以繼續幹了。
PS: 想不想知道 clear 為什麼是女性?