【问题标题】:Why last object written to file gets repeated in cpp and how to solve it [duplicate]为什么最后一个写入文件的对象在cpp中重复以及如何解决它[重复]
【发布时间】:2012-09-26 11:02:09
【问题描述】:

可能重复:
Reading from text file until EOF repeats last line

我正在使用以下代码将数据写入文件

//temp is class object
fstream f;
f.open ("file", ios::in|ios::out|ios::binary);
for(i=0;i<number_of_employees ;++i)
{
temp.getdata();
f.write( (char*)&temp,sizeof(temp));
}
f.close();

temp 是下面类的对象

class employee
 {
 char eno[20];
 char ename[20];
 char desg[20];
 int bpay;
 int ded;
 public:
 void getdata();
 void displaydata();
}

但是当我使用此代码写入数据时,我发现写入文件的最后一个对象被写入了两次。

我从文件中读取的函数是

fstream f;
f.open ("file", ios::in|ios::out|ios::binary);
while(f)
{
f.read((char*)&temp, sizeof(temp));
temp.displaydata();
}
f.close();

以下显示我的文件被读取到 eof 时

Number       :1
Name       :seb
Designation:ceo
Basic Pay  :1000
Deductions :100

Number       :2
Name       :sanoj
Designation:cto
Basic Pay  :2000
Deductions :400

Number       :2
Name       :sanoj
Designation:cto
Basic Pay  :2000
Deductions :400

这是什么原因,我该如何解决?

【问题讨论】:

  • 您不要使用该代码,因为这不是 C++ 代码。请提供真实代码。
  • 如果您发布实际代码可能会有所帮助。此外,除了 POD 类型之外,您写入数据的方法可能是不安全的,即使在那里也不是没有问题。

标签: c++ file


【解决方案1】:

如果问题是重复输出,很可能是你循环的方式造成的。请发布确切的循环代码。

如果循环基于您从 getdata() 接收的数据,您还需要仔细查看您输入的内容。您可能没有收到预期的结果。

当然,如果没有真正的代码,这些几乎只是猜测。

【讨论】:

    【解决方案2】:

    问题的原因很简单:您没有检查 在使用结果之前读取已成功。最后一次读取遇到 文件结尾,在不更改变量值的情况下失败,并且 然后显示旧值。正确的方法来做什么 你想要做的是:

    while ( f.read( reinterpret_cast<char*>( &temp ), sizeof( temp ) ) ) {
        temp.displaydata();
    }
    

    然而,你正在尝试做的事情是非常脆弱的,并且可能 很容易与编译器的下一个版本中断。你的事实 代码需要一个reinterpret_cast 应该是一个红旗,表示 你正在做的事情是非常不可移植的并且依赖于实现。 你需要做的是首先,定义一个二进制格式(或使用一个 已定义,如 XDR),然后根据它将数据格式化为 char 缓冲区(我会为此使用 std::vector&lt;char&gt;),最后使用 f.write 在这个缓冲区上。在阅读时,情况正好相反:你阅读了一个 将char 块放入缓冲区,然后从中提取数据。 std::ostream::writestd::istream::read 不适合写作和 读取原始数据(无论如何这毫无意义);如果他们是,他们会 采取void*。它们用于写入和读取预先格式化的数据。

    【讨论】:

      【解决方案3】:

      write((char*)object, sizeof(object))将对象写入文件是自找麻烦!

      不如为类写一个专用的write函数:

      class employee {
        ...
        void write(ostream &out) {
          out.write(eno, sizeof(eno));
          out.write(ename, sizeof(ename));
          out.write(desg, sizeof(desg));
          out.write((char*)&bpay, sizeof(bpay));
          out.write((char*)&ded, sizeof(ded));
        }
        void read(istream &in) {
          in.read(&eno, sizeof(eno));
          in.read(&ename, sizeof(ename));
          ...
          in.read((char*)&bpay, sizeof(bpay));
          in.read((char*)&ded, sizeof(ded));
        }
      
      }
      
      ostream &operator <<(ostream &out, employee &e) {
        e.write(out);
        return out;
      }
      istream &operator >>(istream &in, employee &e) {
        e.read(in);
        return in;
      }
      

      完成后,您可以使用:

      f << temp;
      

      将您的员工记录写入文件。

      但请注意,即使这样也不是很好,因为至少就整数而言,我们变得非常依赖平台,它是 int 的 size 和字节序的整数。

      【讨论】:

        猜你喜欢
        • 2016-07-18
        • 2020-10-08
        • 2013-04-18
        • 2017-08-15
        • 2021-08-11
        • 1970-01-01
        • 2020-02-29
        • 2013-08-04
        • 2021-12-02
        相关资源
        最近更新 更多