c++验证数字并停止无限循环
我正在做一个控制台应用程序,我将一个整数传递给应用程序,它工作正常,但如果我传递一个字母,它就会变得疯狂,
int opt=0;
std::cout<<"Pick lang:"<<'\n';
std::cout<<"1.[es-ES]:"<<'\n';
std::cout<<"2.[en-US]:"<<'\n';
std::cin >> opt;
while(opt<1 || opt>2)
{
std::cout<<"\nERROR!"<<'\n';
std::cout<<"Pick lang again:"<<'\n';
std::cout<<"1.[es-ES]:"<<'\n';
std::cout<<"2.[en-US]:"<<'\n';
std::cin >> opt;
}
我尝试使用 isdigit() 但得到相同的结果。谢谢
I'm doing a console app, I'm passing an integer to the app and it works ok, but if I pass a letter, it goes crazy,
int opt=0;
std::cout<<"Pick lang:"<<'\n';
std::cout<<"1.[es-ES]:"<<'\n';
std::cout<<"2.[en-US]:"<<'\n';
std::cin >> opt;
while(opt<1 || opt>2)
{
std::cout<<"\nERROR!"<<'\n';
std::cout<<"Pick lang again:"<<'\n';
std::cout<<"1.[es-ES]:"<<'\n';
std::cout<<"2.[en-US]:"<<'\n';
std::cin >> opt;
}
I tried to use isdigit() but I get the same result. Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
执行cin>>后提取时,您想检查 cin 流是否仍然良好。如果您希望 cin 提取一个数字,但它会得到其他内容,例如。就像一封信,那么流将被设置为错误状态,这就是为什么你会看到它“变得疯狂”。
你要做的就是输入后检查cin是否还好。如果它处于不良状态,您需要清除其标志,然后删除流中的任何垃圾数据。如果不这样做,那么 cin 的后续使用将无法正常工作。
以您的代码片段为例,您可以将其更改为如下所示:
编辑: cin 错误处理中出现轻微错误。已更正,现在应该可以工作了。 :)
After performing cin >> extraction, you want to check if the cin stream is still good or not. If you expect cin to extract a number but it gets something else instead, eg. like a letter, then the stream will be set to a bad state and that's why you see it 'going crazy'.
What you have to do is after input, check if cin is still good. If it's in a bad state, you need to clear its flags and then remove out any of the junk data in the stream. If you don't, then subsequent uses of cin will simply fail to function.
Taking your code snippet for example, you can change it to something like this:
Edit: whoops minor error in the cin error handling. Corrected and should be working now. :)
问题是调用
std::cin >>> opt
无法解析字符并立即返回(不消耗缓冲区),然后它找到相同的内容并失败......您应该检查操作的结果并对其做出反应。一种可能是检查失败位(
std::cin.fail()
)并使整个操作失败或消耗缓冲区的部分(可能是单个字符,也可能更多,具体取决于您想要的方式)应用程序的行为)。最简单的事情可能不是读入数字,而是读入字符,然后与预期字符进行比较:
The problem is that the call
std::cin >> opt
is failing to parse the character and returns immediatly (without consuming the buffer), then it finds the same contents and fail....You should check the result of the operation and react to it. One possibility would be checking the fail bit (
std::cin.fail()
) and failing the whole operation or consuming parts of the buffer (maybe a a single character, maybe more, depending on how you want the application to behave).The simplest thing would probably be not reading into a number, but rather a character, and then comparing with the expected character:
更多信息: http://www.augustcouncil.com/~tgibson /tutorial/iotips.html
more info here: http://www.augustcouncil.com/~tgibson/tutorial/iotips.html
当您插入字母时,会发生这种情况:
operator>>
从流中提取字符并尝试将它们转换为数字;opt
可能未受影响(标准将这些东西委托给语言环境库,这是我从未真正理解的 C++ 区域 - 对于足够勇敢的人来说,它位于 §22.2.2.1.2);opt
保持原样,所以循环继续;std::cin>>时opt;
,operator>>
看到状态仍然是ios::failbit
,因此它甚至不会尝试提取任何内容;要解决该问题,您应该清除错误状态并从输入缓冲区中删除“错误”字符。由于您可能不想将所有代码添加到每个 cin>>,因此创建一个函数来处理这个常见问题很有用;就我个人而言,我创建了这个小标头 (
AcquireInput.hpp
),它已被多次证明很有用:When you insert a letter this happens:
operator>>
extracts characters from the stream and try to convert them to a number;ios::failbit
and returns;opt
probably is untouched (the standard delegates this stuff to the locale library, which is a zone of C++ that I never really understood - for the brave enough, it's at §22.2.2.1.2);opt
is left as it is, the loop continues;std::cin >> opt;
,operator>>
sees that the state is stillios::failbit
, so it doesn't even try to extract anything;To fix the problem, you should clean the error state and remove the "wrong" characters from the input buffer. Since you probably don't want to add all that code to every
cin>>
, it's useful to create a function to deal with this common problem; personally, I created this little header (AcquireInput.hpp
) that has proven useful many times: