而当 CIN 的输入是'dot'时循环到无穷大
while loop to infinity when the input of a cin is a 'dot'
我在使用cin方法获取变量时遇到了麻烦。当输入的是数字时没有问题,但是当输入的是像点[.]这样的特殊字符时,while循环循环到无限远。我做错了什么?
cout << "What is your race" <<endl<<"1.Humann2.trolln3.zombie"<<endl;
cin >> *race;
while(*race<1||*race>3)
{
system("cls");
cout << "Wrong choice"<<endl<< "What is your race" <<endl<<"1.Humann2.trolln3.zombie"<<endl;
cin >> *race;
}
我搜索了答案,我应该刷新缓冲区,但我不知道如何做到这一点。我对c++还是个新手。谢谢
将race
设置为字符,然后您将能够:
while (*race < '1' || *race > '3')
这可能就是你想要达到的目标。
解释:
当您将cin >>
转换为int时,它将给定的ASCII字符串转换为整数值。.
不具有整数意义,因此它不被读取到race
和failbit
被设置-进一步>>s是无操作的,直到您清除它们。但是,如果您将cin >>
转换为char
并将其与其他char
进行比较(实际上是它们的ASCII码),您将能够轻松检查它。
这个例子完全再现了你的问题:
#include <iostream>
int main()
{
int i = 5;
while (i < 1 || i > 3)
{
std::cin >> i;
}
}
的情况如下:当operator>>
读取整数失败时(例如,当您键入点并按enter键时),您键入的将保留在流中,包括换行符。所以在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');
}
}
}
您的代码有几个问题。第一种是你不知道验证您的输入是否成功;的正确条件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 racen"
"1. Humann"
"2. Trolln"
"3. Zombien" << std::flush;
race = getRace( std::cout );
if ( race < 0 ) {
std::cout << "Wrong choice" << std::endl;
}
}
注意,通过一行输入,可以避免任何问题重置格式错误,跳过错误输入或重新同步
除了接受的解决方案之外,另一种解决方案是清除cin的failbit
并忽略最后的输入,如下所示:
cout << "What is your race" <<endl<<"1.Humann2.trolln3.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.Humann2.trolln3.zombie"<<endl;
cin >> *race;
}
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- 无穷大而循环时具有递归函数
- Matlab 如何知道有一个 .mex64 文件并避免无穷大"compiling"循环
- MIPS :循环进入无穷大
- unsigned int导致循环为无穷大
- 链表循环达到无穷大
- 而当 CIN 的输入是'dot'时循环到无穷大
- 开关内部的循环变为无穷大