首先給出代碼,這段代碼的原意是,從鍵盤輸入a,然後判斷a是否讀取成功,如果沒有就打印信息,並且再次讓用戶輸入,直到用戶輸入一個合法輸入才停止。
c++代碼
#include <iostream>
using namespace std;
int main() {
int a=0;
while (1) {
if (!(cin >> a))
{
cout << "I'm in the loop!\n";
}
else
break;
}
cout << a << endl;
return 0;
}
然而,上面的代碼運行時,如果在鍵盤種輸入一個字符而不是數字,就會進入死循環,而不是打印信息後再次接收用戶的鍵盤輸入。
對於這個現象的解釋,是不合法輸入導致輸入流有狀態錯誤標記,並且輸入的不合法字符一直留在輸入流。當判斷!(cin>>a)
時,會先看到輸入流錯誤標記,直接判斷條件成立,於是輸出那段信息,然後又進入循環。因此,需要做兩件事情。
- 清除輸入流的錯誤標記
- 將輸入流中的非法字符中清除
這兩步缺一不可。於是代碼改成這樣就可以了。
#include <iostream>
using namespace std;
int main() {
int a=0;
while (1) {
if (!(cin >> a))
{
cout << "I'm in the loop!\n";
cin.clear(); // 清除輸入流錯誤標記
cin.ignore(1024,'\n');// 取走剛纔輸入流中的字符
// cin.ignore()默認取走一個字符
}
else
break;
}
cout << a << endl;
return 0;
}
c代碼
#include <cstdio>
int main() {
int a = 0;
while (1) {
if (!scanf("%d",&a))
{
printf("I'm in the loop!\n");
}
else
break;
}
printf("%d\n",a);
return 0;
}
上面這個代碼等價於那段c++的代碼,
解決方案:
#include <cstdio>
int main() {
int a = 0;
while (1) {
if (!scanf("%d",&a))
{
printf("I'm in the loop!\n");
rewind(stdin);
}
else
break;
}
printf("%d\n",a);
return 0;
}