为什么最后一个写入文件的对象在cpp中重复,以及如何解决它

Why last object written to file gets repeated in cpp and how to solve it

本文关键字:何解决 解决 文件 最后一个 对象 cpp 为什么      更新时间:2023-10-16

可能重复:
从文本文件读取直到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

造成这种情况的原因是什么?我该如何解决?

如果问题是重复输出,则很可能是由循环方式引起的。请公布确切的循环代码。

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

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

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

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

然而,你正试图做的事情是非常脆弱的,而且可能很容易与编译器的下一个版本决裂。事实上代码需要reinterpret_cast应该是一个红色标志,指示您所做的是非常不可移植的,并且依赖于实现。您需要做的是首先定义一个二进制格式(或者使用已经定义,如XDR),然后根据它将数据格式化为char缓冲区(我会使用std::vector<char>),最后使用CCD_ 4。在阅读方面,情况正好相反:将char的块放入缓冲器中,然后从中提取数据。CCD_ 6和CCD_读取原始数据(这毫无意义);如果是的话,他们会取CCD_ 8。它们用于写入和读取预先格式化的数据。

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;

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

但请注意,即使这样也不太好,因为至少就整数而言,我们正变得非常依赖于平台,ito是int的大小,ito是int.