你的代碼有幾個問題。首先是你不要 驗證你的輸入成功;對於 while
正確的條件應該是:
while (!cin || (*race < 1 || *race > 3))
書面,如果輸入失敗(這是發生了什麼事,當你 輸入'.'
,假設race
的類型爲int*
),然後*race
包含其以前的價值,不管那是什麼。
第二個是如果你從cin
得到一個錯誤,你不清楚 它。一旦流處於錯誤狀態,它將保持這種狀態,直到您明確清除它爲止。如果cin
失敗,你需要執行:
cin.clear();
某處循環。
第三個是,如果cin
失敗了,你不提取其 使它失敗,使清除錯誤狀態後,你需要 提取它的字符。鑑於你的結構化對話的方式,你可能 要不顧一切,直到行的末尾:
cin.ignore(INT_MAX, '\n');
您可能要做到這一點,即使cin
沒有失敗,無論是在環 (如果由於*race < 1 || *race > 3
條件而被輸入),或者在 成功的情況下。或者,你可能要轉移到閱讀的線條, 並確保該行只包含 你感興趣的字符後的空白。
這最後的解決方案是一個我會採用,因爲它處理了相當多 所有上述問題。所以,我的代碼看起來是這樣的:
// return -1 on error in input,
// throw exception on (unexpected) end of file
int
getRace(std::istream& source)
{
std::string line;
if (!std::getline(source, line)) {
throw std::ios_base::failure("Unexpected end of file");
}
std::istringstream tmp(line);
int results;
return tmp >> results >> std::ws && tmp.get() == EOF
? results
: -1;
}
// ...
int race = -1;
while (race < 0) {
std::cout << "What is your race\n"
"1. Human\n"
"2. Troll\n"
"3. Zombie\n" << std::flush;
race = getRace(std::cout);
if (race < 0) {
std::cout << "Wrong choice" << std::endl;
}
}
注意,通過線路輸入,您避免出現任何問題與 重置格式錯誤,跳過錯誤輸入或 情況下錯誤的重新同步。
什麼是種族? –
變數競賽是一個INT – Rps
@RPS:不,它不是。如果'race'的類型是'int',那麼'* race'將是一個錯誤,編譯器會拒絕它。 –