【问题标题】:C++ - why cin.eof() read last char twice? [duplicate]C++ - 为什么 cin.eof() 读取最后一个字符两次? [复制]
【发布时间】:2012-10-31 21:26:02
【问题描述】:

可能重复:
Why is iostream::eof inside a loop condition considered wrong?


我有一个很简单的问题...

#include<iostream>
using namespace std;
int main()
{
    char x;
    while(!cin.eof())
    {
        cin>>x;
        cout<<"char: "<< x << endl;
    }
    return 0;
}


为什么当我尝试在 Linux 上运行此代码时:
./file_name 结果是:
字符:a
字符:b
字符:c
字符:d
字符:d
当 test_file.txt 只有:
abcd

【问题讨论】:

标签: c++ eof cin


【解决方案1】:

通过失败输入操作检测到文件结尾。

所以,在

    cin>>x;
    cout<<"char: "<< x << endl;

即使输入操作失败,也会执行输出语句。

当它失败时,它不会更新x

不是测试.eof(),而是测试.fail()

您可以通过直接使用流对象作为条件来做到这一点,例如

#include<iostream>
using namespace std;
int main()
{
    char x;
    while( cin >> x )
    {
        cout<<"char: "<< x << endl;
    }
}

这里的表达式cin &gt;&gt; x 执行一个可能更新x 的输入操作,并作为它的表达式结果 返回对流的引用,即对cin。所以cin 被直接用作条件。这会调用到布尔值的转换,该布尔值的定义使其本身等效于!cin.fail()(即,表达式cin &gt;&gt; x 作为条件等效于编写!(cin &gt;&gt; x).fail(),或者,作为逗号表达式,(cin &gt;&gt; x, !cin.fail())) .

【讨论】:

    【解决方案2】:

    您正在使用稍微错误的模式来读取文件。正确的形式是

    while(cin >> x) {
        cout<<"char: "<< x << endl;
    }
    

    请记住,eof 会告诉您如果您尝试阅读超过输入末尾的内容;它不会告诉您是否即将这样做。您的原始代码第一次读取d,发现它没有尝试读取结尾,然后尝试再次读取。此读取失败,但您现在位于循环内,并且 x 具有上一次迭代的值 d,因此它会再次打印。

    上面的代码在尝试读入x之后测试了流的状态(顺便说一句,它不仅会捕获文件结尾,还会捕获错误);因此在第一次读取失败后,循环将不会被执行。

    【讨论】:

      【解决方案3】:

      你必须使用文件大小的for循环来避免空字符

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-27
        • 2014-12-21
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        • 2017-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多