您的代码存在几个问题。第一个是你不
验证您的输入是否成功;的正确条件
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;
}
}
请注意,通过一行输入,您可以避免任何问题
重置格式错误,跳过错误输入或重新同步
错误的情况。