3

私は次の構造体を持っています

struct MyStruct
{
    int     param1;
    float   param2;
    double  param3;
}

を使用してバイナリファイルに書き込むことができます

fstream binary_file(file, ios::out|ios::binary); 
binary_file.seekg(0, ios::beg);
binary_file.write((char *)aStruct,sizeof(MyStruct));
binary_file.close();

そして私はそれを使用してそれを回復することができます

ifstream binary_file;
binary_file.open(file, ios::binary);
binary_file.seekg(0, ios::beg);
binary_file.read((char *)aStruct, sizeof(MyStruct));
binary_file.seekg (0, ios::end);
binary_file.close();

これはすべてうまくいきます。ここで、構造体の定義を次のように変更します

struct MyStruct
{
    int     param1;
    float   param2;
    double  param3;
    int     paramA;
    float   paramB;
    double  paramC
}

問題は、定義が変更される前に書き込まれたファイルを読み取る場合、param1、param2、および param3 が常に正しく設定され、paramA、paramB、および paramC にジャンクが割り当てられないことを確認できるかどうかです。パラメータは、構造体の最後にのみ追加されます。

参照によると、指定されたビット数を読み取る前に eof が発生した場合、ifstream 読み取り関数は停止する必要があるため、うまくいけば、これは聞こえるほど簡単です。私のテストでは、質問に対する答えが「はい」であることも示されていますが、たとえばバイナリファイルのパディングについて読んでいて、それがどのように機能するかを完全には理解していないので、皆さんに確認したいと思います.

4

2 に答える 2

4

問題は、定義が変更される前に書き込まれたファイルを読み取った場合、param1、param2、および param3 が常に正しく設定されるかどうかです。

はい、あなたはそれを確信することができます。

paramA、paramB、および paramC にジャンクが割り当てられないことを確認できますか?

これも正しいですが、注意点が 1 つあります。これらのフィールドがコンストラクターで初期化されない限り、読み取り後も初期化されないままになります (つまり、"ジャンク" が含まれます)。

struct最後に、このトリックはバイナリ ファイルから1 つを読み取る場合にのみ機能することに注意してください。structそのようなの配列を保存する必要がある場合はsizeof、データの書き出し時に有効だった を保存する必要があります。そうしないと、配列を正しく分割できません。

明らかに、別のコンパイラまたは同じコンパイラの別のバージョンに変更すると、新しいフィールドをstruct.

于 2013-06-05T15:45:54.957 に答える