2012-04-27 98 views
14

在C++中,你如何處理錯誤的輸入?就像,如果程序要求一個整數,當你鍵入一個字符時,它應該能夠做一些事情,然後循環來重複輸入,但是當你需要一個整數時輸入一個字符,循環變得無限,反之亦然。如何處理錯誤的數據類型輸入

回答

32

程序進入一個無限循環的原因是因爲std::cin的壞輸入標誌設置由於輸入失敗。要做的是清除該標誌並丟棄來自輸入緩衝區的錯誤輸入。

//executes loop if the input fails (e.g., no characters were read) 
while (std::cout << "Enter a number" && !(std::cin >> num)) { 
    std::cin.clear(); //clear bad input flag 
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard input 
    std::cout << "Invalid input; please re-enter.\n"; 
} 

參見the C++ FAQ對於這一點,和其它實例,包括添加的最小和/或最大爲條件。

另一種方法是讓輸入一個字符串並將其轉換爲與std::stoi整數或允許檢查轉換一些其他的方法。

+1

我在問這裏之前已經做了一些研究。我看到他們把cin.ignore(1000,'\ n');這是做什麼的?還!(cin >> num)返回一個布爾值?我不知道 – Zik 2012-04-27 11:42:20

+0

感謝站點 – Zik 2012-04-27 11:48:10

+1

@Marvin,'cin.ignore(1000,'\ n')'忽略/丟棄輸入緩衝區中的字符,直到1000被丟棄,或者遇到換行符,以先到者爲準。這是擺脫線條的好方法。您將在parashift示例中看到,它們使用流的最大大小而不是1000來計算最大長度的一行。我使用'cin.sync()',因爲當我這樣做時,我想和用戶保持平等(不讀下一行),所以我放棄了一切。最後,'cin'有一個'operator void *',所以它不能轉換成布爾值。 – chris 2012-04-27 11:48:20

0

測試輸入以查看它是否是您的程序所期望的。如果不是,提醒用戶他們提供的輸入是不可接受的。

0

如果ascii的值在65 t0 90或97到122之間,你可以通過ASCII值檢查它是否是字符。

3

頂尖的投票答案涵蓋了解決方案非常好。

除了這個問題的答案,這可能有助於想象這是怎麼回事好一點:

int main() 

    int input = 1;//set to 1 for illustrative purposes 
    bool cinState = false; 
    string test = "\0"; 
    while(input != -1){//enter -1 to exit 
     cout << "Please input (a) character(s): ";//input a character here as a test 
     cin >> input; //attempting to input a character to an int variable will cause cin to fail 
     cout << "input: " << input << endl;//input has changed from 1 to 0 
     cinState = cin;//cin is in bad state, returns false 
     cout << "cinState: " << cinState << endl; 
     cin.clear();//bad state flag cleared 
     cinState = cin;//cin now returns true and will input to a variable 
     cout << "cinState: " << cinState << endl; 
     cout << "Please enter character(s): "; 
     cin >> test;//remaining text in buffer is dumped here. cin will not pause if there is any text left in the buffer. 
     cout << "test: " << test << endl; 
    } 
    return 0;  
} 

傾倒在緩衝區內文本的一個變量是不是特別有用,但它有助於想像爲什麼cin.ignore()是必要。

我注意到輸入變量的變化,因爲如果你在條件中使用一個輸入變量作爲while循環或switch語句,它可能會陷入死鎖,或者它可能會滿足一個條件,期待,這可能更容易混淆調試。