【问题标题】:C++ file handling (structures)C++ 文件处理(结构)
【发布时间】:2009-01-13 18:23:57
【问题描述】:

以下代码,当使用 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();
}

【问题讨论】:

    标签: c++ file file-io fstream


    【解决方案1】:

    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,这将阻止它进入循环。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        由于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)
        

        更好的策略是在read 调用之后立即检查eof

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            【解决方案5】:

            酷。 另一种方式(感谢专家交流,我在那里问了同样的问题:-))

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-07-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多