2

下面的代码,当用 g++ 编译和运行时,打印 '1' 两次,而我希望 '1' 只打印一次,因为我将单个结构转储到文件中,但是在回读时它似乎正在读取两个结构. 为什么?

#include <iostream.h>
#include <fstream.h>

int main(){
    struct student
    {
        int rollNo;
    };
    struct student stud1;
    stud1.rollNo = 1;

    ofstream fout;
    fout.open("stu1.dat");
    fout.write((char*)&stud1,sizeof(stud1));
    fout.close();

    ifstream filin("stu1.dat");
    struct student tmpStu;
    while(!filin.eof())
    {
          filin.read((char*)&tmpStu,sizeof(tmpStu));
      cout << tmpStu.rollNo << endl; 
    }
    filin.close();
}
4

5 回答 5

11

eof仅在读取失败后设置,因此读取运行两次,第二次不修改缓冲区。

试试这个:

while(filin.read((char*)&tmpStu,sizeof(tmpStu)))
{
    cout << tmpStu.rollNo << endl; 
}

或者

while(!filin.read((char*)&tmpStu,sizeof(tmpStu)).eof())
{
    cout << tmpStu.rollNo << endl; 
}

Read 在调用时返回对 filin 的引用,如果流仍然良好,它将评估为 true。当 read 无法读取更多数据时,引用将评估为 false,这将阻止它进入循环。

于 2009-01-13T18:29:07.147 回答
5

您的 while 循环执行了两次,因为 EOF 条件在第一次尝试读取文件末尾之后才为真。所以 cout 被执行了两次。

于 2009-01-13T18:29:40.157 回答
2

由于确切的方式eofread工作,这会打印 1 两次。如果您在文件的最后,read将失败,然后调用eof 返回true。如果您没有尝试读取超过文件末尾的内容,eof则将返回 false,因为流未处于 EOF 状态,即使没有更多数据可供读取。

总而言之,您的调用如下所示:

eof - false (at beginning of file)
read (at beginning of file)
eof - false (now at end of file, but EOF not set)
read (at end of file. fails and sets EOF state internally)
eof - true (EOF state set)

更好的策略是在通话eof后立即检查。read

于 2009-01-13T18:33:51.460 回答
1

我相信这是因为您正在检查 filin.eof() 并且直到您第二次阅读才会如此。

这里。它注意到 eofbit 设置为“......在读取 n 个字符之前到达字符源的末尾......”。在您的情况下,您不会在第二次阅读之前点击 EOF。

于 2009-01-13T18:30:53.807 回答
0

凉爽的。另一种方式(由专家交流提供,我在那里问了同样的问题:-))

while(filin.peek() != EOF)
{
    filin.read((char*)&tmpStu,sizeof(tmpStu));
    cout << tmpStu.rollNo << endl;
}
于 2009-01-13T19:11:23.943 回答