簡體   English   中英

使用cin.fail()時發生無限循環

[英]Inifinite loop when using 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;
}

僅僅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故障) 應引發異常。 相反,您期望輸入錯誤的內容。

這在isocpp.org常見問題解答中有介紹 建議使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM