你的代码有几个问题。首先是你不要 验证你的输入成功;对于 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'将是一个错误,编译器会拒绝它。 –