C++判断输入结束的讨论

先看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…

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s