-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();
}

しかし、このコードを使用してデータを書き込むと、最後にファイルに書き込まれたオブジェクトが 2 回書き込まれることがわかりました。

ファイルから読み取る私の機能は

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();
}

ただし、まさにあなたがやろうとしていることは非常に壊れやすく、コンパイラの次のリリースで簡単に壊れる可能性があります。コードに が必要であるという事実は危険信号である必要reinterpret_castがあります。これは、実行していることは非常に移植性が低く、実装に依存していることを示しています。あなたがする必要があるのは、最初にバイナリ形式を定義し(またはXDRのようにすでに定義されているものを使用し)、それに従ってデータを charバッファにフォーマットし(私はこれに使用std::vector<char>します)、最後 f.writeにこのバッファで使用します。読み取り時は逆です。 のブロックをcharバッファーに読み取り、そこからデータを抽出します。 生データの書き込みと読み取り用ではありません(とにかく意味がありませんstd::ostream::writeもしそうなら、彼らは取るだろうstd::istream::readvoid*. それらは、事前にフォーマットされたデータの書き込みと読み取り用です。

于 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 に答える