考虑以下代码,其接受整数输入,然后打印cin流状态:
#include <iostream>
using namespace std;
int main()
{
int number;
cout<<"Enter a number \n";
cin>>number;
cout<<cin.rdstate()<<endl;
return 0;
}
如果输入的数字是“zzzz”,则rdstate返回值4。
如果输入的数字是“10 zzzz”,那么rdstate返回值0,number的值为10,输入流中有“zzzz”。
我的问题是:
1.为什么输入“10 zzzz”不被视为无效输入(至少应该设置一个失败位)。
2.什么是检测和处理这种情况的优雅解决方案。
Thanks!
2条答案
按热度按时间g6baxovj1#
首先,我想问一下你在做什么:
阅读本页以正确使用rdstate()http://www.cplusplus.com/reference/iostream/ios/rdstate/
第二:检查输入是字符串类型还是整数类型,你可能想添加一些额外的东西,它会将输入字符串转换为整数数据,并在输入无效输入时响应错误消息。
这将帮助你。
o0lyfsai2#
如果输入的数字是“zzzz”,则rdstate返回值4。如果输入的数字是“10 zzzz”,那么rdstate返回值0,number的值为10,输入流中有“zzzz”。
为了理解为什么会发生这些,我们需要理解提取操作符(操作符>>)是如何工作的。这里有几个很好的链接开始:
std::cin and handling invalid input
std::istream::operator>>
我们可以在以下几个地方深入挖掘:
operator>>(std::basic_istream)
std::basic_istream<CharT,Traits>::operator>>
std::num_get<CharT,InputIt>::get, std::num_get<CharT,InputIt>::do_get
简单地说,当写入算术类型时,只要字符序列可以准确地解释为该类型的值,就会逐个字符地分析输入。当不再可能这样做时,解析停止,并且使用直到该点为止已经获得的有效值。
“zzzz”表示无效值,而“10 zzzz”允许解析
10
。就解决方案而言,可以改进dennis基于字符串流的answer,以处理尾随字符,如here所示。如果有尾随字符,
!myStream.eof()
将计算为true。此外,除了使用字符串流之外,还有其他选项。例如,
strtol
、std::stoi
。此外,在此上下文中使用输入字符串流而不是字符串流会更好。参见here。