我在使用cin方法获取变量时遇到问题。当输入是一个数字时没有问题,但是当它是一个像[。]这样的特殊字符时, whileloop循环到无限。 我做错了什么?
cout << "What is your race" <<endl<<"1.Human\n2.troll\n3.zombie"<<endl;
cin >> *race;
while(*race<1||*race>3)
{
system("cls");
cout << "Wrong choice"<<endl<< "What is your race" <<endl<<"1.Human\n2.troll\n3.zombie"<<endl;
cin >> *race;
}
我搜索了答案,我应该冲洗缓冲区,但我不知道该怎么做。我是c ++的新手.Thanx
答案 0 :(得分:2)
让race
成为一个字符,然后您就可以:
while (*race < '1' || *race > '3')
这可能就是你想要实现的目标。
说明:
当你cin >>
进入int时,它会将给定的ASCII字符串转换为整数值。 .
没有整数含义,因此未将其读入race
并设置failbit
- 进一步&gt;&gt; s为无操作,直到您清除它们为止。但是,如果您cin >>
进入char
并将其与其他char
(实际上是他们的ASCII代码)进行比较,您就可以毫无困难地进行检查。
答案 1 :(得分:1)
除了接受的解决方案之外的其他解决方案是清除cin的failbit
并忽略最后一个输入,如下所示:
cout << "What is your race" <<endl<<"1.Human\n2.troll\n3.zombie"<<endl;
cin >> *race;
while(*race<1||*race>3)
{
// Clears the state of cin to be in good state
cin.clear();
// Ignores the last input read so that it's not read back again
cin.ignore();
system("cls");
cout << "Wrong choice"<<endl<< "What is your race" <<endl<<"1.Human\n2.troll\n3.zombie"<<endl;
cin >> *race;
}
答案 2 :(得分:1)
此示例完全重现您的问题:
#include <iostream>
int main()
{
int i = 5;
while (i < 1 || i > 3)
{
std::cin >> i;
}
}
这里发生了什么:当operator>>
无法读取整数时(例如,当您键入一个点并按回车键时),无论您输入的是什么都会在流中停留,包括换行符。
因此,在while循环的下一次迭代中,下一个输入已经存在,并且因为它不是有效整数,所以循环永远不会中断。
您需要确保在operator>>
失败时清空流并清除已设置的所有错误标志。
#include <iostream>
#include <limits>
int main()
{
int i = 5;
while (i < 1 || i > 3)
{
if (!(std::cin >> i))
{
// clear streams internal error flags
std::cin.clear();
// ignore what's left in the stream, up to first newline character
// or the entire content, whichever comes first
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
}
答案 3 :(得分:1)
您的代码存在一些问题。首先是你没有
验证您的输入是否成功;正确的条件
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;
}
}
请注意,通过输入一行,可以避免任何问题 重置格式错误,跳过错误输入或重新同步 出现错误。