【问题标题】:File handling not working with fstream after reaching eof?达到 eof 后文件处理不能与 fstream 一起使用?
【发布时间】:2016-02-14 18:26:06
【问题描述】:

根据您的建议,我已按照您的建议更改了代码,但是当将 ios::out 替换为 ios::ate 时仍然存在问题,文件中没有写入任何内容(写入不起作用)。有没有办法检查下一位是否是 eof 而不是读取它然后检查它?正如你所建议的那样。有时当我进行文件处理时,它会显示文件指针的位置为-1,这意味着什么???

代码:

int main ()

{

    char p[80];
    fstream file("text1.txt",ios::out|ios::in); //if ios::ate is added here it results into infinite loop
    cout<<"Starting position of the file is "<<file.tellg()<<endl;
    getch();
    if(file.is_open())
        cout<<"file is open\n";
    else
        cout<<"file is not open\n";
    getch();
    file.seekp(0);
    while(file>>p)
    {
        cout<<p<<endl;
    }
    file.clear();
    cout<<"\nThe current position of the file pointer is "<<file.tellg()<<endl;
    file.seekp(0);
    if(file.eof())
        cout<<"\n the eof\n";
    while(file>>p)
    {
        cout<<p<<endl;
    }
    file.close();
    return 0;
}

输出:

Starting position of the file is 0
file is open
Hello
man
how
are
you

The current position of the file pointer is 21
Hello
man
how
are
you

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    这种从文件读取到达文件末尾会导致同时设置 eof 和 failbit。设置了 Failbit 是因为使用 file.eof() 条件创建读取循环并不表示下一次读取将是流的结尾。它只是说明我们还没有达到 eof,所以:

    while(file.eof())
    {
    file >> p;
    }
    

    最后一次读取可能只是 eof,我们将使用未初始化的数据。如果发生这种情况,将不会在 p 中提取任何字符,并且会设置 eof 和失败标志。

    使用 c++98 时需要使用以下方法将故障位重置为 false:

    file.clear();
    

    为避免出现错误读数的情况,您应该从文件中的 while 条件中提取字符:while(file &gt;&gt; p)。我推荐thisthis 堆栈溢出问题。

    所以正确的 C++98 代码应该是这样的:

    while(file >> p)
    {
      std::count << p << std::endl;
    }
    file.clear();
    file.seekp(0);
    while(file >> p)
    {
      std::count << p << std::endl;
    }
    file.close();
    

    我在 Visual Studio 2013 上对其进行了几次测试,每次都能正常工作。

    考虑ios::ate 模式: ios::outios::in 是说明我们如何打开相关文件的修饰符。如果您想从文件中读取某些内容,则需要使用ios::out 标志,而对于写入,您需要使用ios::in

    另一方面,ios::ate 只是告诉编译器打开文件并立即转到文件末尾。所以如果你用ios::ate 替换ios::out 是不可能的,程序将在file &lt;&lt; "Hello..."; 上上升failflag。 如果你只是想追加数据,但从文件的开头读取,你应该使用ios::app,因为它告诉在每次写入之前寻找eof。

    【讨论】:

    • 我在 gcc 编译器的代码块中也试过这个,这并不每次都有效,如果我使用 ios::ate 这整个不起作用。为什么我每次都需要清除流达到eof之后??
    • @Harshul 我重写了我的答案,以前的答案很糟糕,甚至没有触及问题的表面。希望这次会有所帮助:)
    • Konrad 'Zegis' 你的回答对我很有帮助,但仍然给我留下了问题,希望你也能帮助我解决这些问题
    • @Harshul tellg() 在设置失败位时返回 -1。并考虑有关窥视下一点的问题,请参阅this question
    猜你喜欢
    • 2013-01-24
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 2011-06-10
    • 2020-02-24
    • 2021-03-19
    相关资源
    最近更新 更多