-4

可能重复:
从文本文件中读取直到 EOF 重复最后一行

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

//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

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

4

3 回答 3

2

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

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

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

于 2012-10-05T10:07:53.010 回答
1

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

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

Exactly what you're trying to do, however, is very fragile, and could easily break with the next release of the compiler. The fact that your code needs a reinterpret_cast should be a red flag, indicating that what you're doing is extremely unportable and implementation dependent. What you need to do is first, define a binary format (or use one that's already defined, like XDR), then format your data according to it into a char buffer (I'd use std::vector<char> for this), and finally use f.write on this buffer. On reading, it's the reverse: you read a block of char into a buffer, and then extract the data from it. std::ostream::write and std::istream::read are not for writing and reading raw data (which makes no sense anyway); if they were, they'd take void*. They're for writing and reading pre-formatted data.

于 2012-10-05T10:25:15.810 回答
0

将对象写入文件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 的大小,以及 int 的字节序。

于 2012-10-05T09:49:30.020 回答