2014-10-10 57 views
0

每次輸入無法轉換爲整數的東西時,我都會收到一個無限循環。有什麼建議麼?使用cin.fail時的無限循環()

cout << "Selection: "; 
cin >> choice; 
while((choice < 0)||(choice > 6)||(cin.fail())) { 
    cout << "That isn't a number." << endl; 
    cin.clear(); 
    cout << "Selection: "; 
    cin >> choice; 
} 
+0

可能重複(http://stackoverflow.com/questions/257091/how-do-i-flush-the-cin-buffer) – edmz 2014-10-10 15:28:03

回答

6

只是clear ING是不夠的:cin會一次又一次地讀取字符。 你需要ignore吧。

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')是實現這一點的常用方法。


另一種方法是將整行讀取爲字符串,然後解析它(如C#/ Java ecc)。在代碼方面則可能是:

string s; 
getline(cin, s); 
int n = std::stoi(s); 

注意std::stoi可以拋出std::invalid_argumentstd::out_of_range。使用這種方法,你不必忽略任何東西(因此更容易處理/學習),儘管你可能需要捕捉可能的例外。

考慮到即使被其他語言使用,此方法在邏輯上也不正確:對於特殊情況(例如,內部I/O故障),應拋出異常而只有。相反,錯誤的用戶輸入是您期望的。

+0

請注意,該調用(不帶第二個參數)將丟棄整個文件的內容。我想你的意思是使用''n''作爲第二個參數。 – 0x499602D2 2014-10-10 15:55:16

+0

我不會爲用戶輸入推薦'std :: stoi'。由於輸入無效,導致程序終止並出現異常是沒有意義的。 – 2014-10-10 15:59:56

+0

@ 0x499602D2雖然在某些情況下有些人可能會忽略EOF,但這是一個很好的建議。謝謝。 – edmz 2014-10-10 16:03:57

1

這包括在isocpp.org faq。它建議以while (std::cin >> i)的形式使用循環,以便循環在提取失敗時終止。提取將繼續失敗,因爲std::cin不會從輸入流中提取無效字符。要放棄這些,您需要使用std::cin.ignore。一般情況下,您可以將任意大的數字作爲第一個參數,但使用std::numeric_limits<std::streamsize>::max()#include <limits>)代替地址。

循環可以簡潔地寫爲:

while(!(std::cin >> choice) || (choice < 0) || (choice > 6)) { 
    cout << "Invalid choice." << endl; 
    std::cin.clear(); 
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
} 

或者,你可以把提示的循環條件:

while((std::cout << "Selection: ") 
     && (!(std::cin >> choice) || (choice < 0) || (choice > 6))) { 
    cout << "Invalid choice." << endl; 
    std::cin.clear(); 
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
} 

沒有必要爲「無效字符」的診斷,因爲這是涵蓋!(std::cin >> choice)。舉例來看:

Selection: a 
Invalid choice. 
Selection: b 
Invalid choice. 
Selection: c 
Invalid choice. 
Selection: d 
Invalid choice. 
Selection: 15 
Invalid choice. 
Selection: 10 
Invalid choice. 
Selection: 5 
的[?我如何刷新CIN緩衝]
+0

如果鏈接中斷,您應該添加*爲什麼*此更改需要進行。 – OMGtechy 2014-10-10 15:40:30