先看2段代码:
[cpp title=”Method 1″]
int a;
while(cin>>a)
{
cout<<a<<endl;
}
[/cpp]
[cpp title=”Method 2″]
int a;
while(cin.good())
{
cin>>a;
cout<<a<<endl;
}
[/cpp]
乍一看, 两者似乎都能判断出输入结束, 然而, 当输入出现错误时, 看下列例子:
input:
1 2 a
output 1:
1
2
output 2:
1
2
2
第二种方法却多了一个输出. 仔细观察, 发现两者从输入流读取和判断结束的顺序存在不同:
Method 1:
从输入流读取->判断流的状态->输出->…
Method 2:
判断流的状态->从输入流读取->输出->…
当循环进行到第三次时, Method 1先进行读取, 发现’a’不满足int, 于是返回0, 跳出循环, 故有2次输出. 而Method 2 先进行判断, 由于此时刚刚成功读完第二个数据, 第三个还未读, 流的状态cin.good()为true, 故进入第三个循环, 尝试读入一个数, 发现’a’不满足int, 于是a的值不会被覆盖, a的值仍为2, 故又输出一个2. 之后由于刚才读取失败置cin.good()为false, 跳出循环.
可见, 用cin.good()判断输入结束是可能存在问题的, 需作如下修改:
[cpp title=”Method 3″]
int a;
cin>>a;
while(cin.good())
{
cout<<a<<endl;
}
[/cpp]
此时先进行读取再判断流的状态, 可以正常判断输入结束.
另外, 参考http://www.cplusplus.com的解释, 如下情况时cin.good()会被置false:
“The function returns true if none of the stream’s error flags (eofbit, failbit and badbit) are set.”
即eofbit, failbit, badbit中任何一个被触发即置cin.good()为false.
注意到cin.bad()并不是cin.good()的反面, 它只对应badbit.
关于这三个标志何时被触发有下表:
flag | error |
---|---|
eofbit | The end of the source of characters is reached during its operations. |
failbit | The input obtained could not be interpreted as an element of the appropriate type.
Notice that some eofbit cases will also set failbit. |
badbit | An error other than the above happened. |
输入结束将导致eofbit和failbit, 输入类型不符将导致failbit, 其它将导致badbit.
吐槽: 这货害我在ZOJ上浪费了不下30次submit…