目標: ファイルから 1 回読み取るだけで、構造全体の割り当てが完了します。毎回 1 つのデータを抽出し、それを構造の特定の要素に割り当ててからループするのではなく、面倒に思えます。
原則: 構造体と構造体配列はどちらもメモリ内の連続したアドレスの内容ですが、位置合わせ効果を実現するために中央にパディングが行われます。しかし、データをパディングと一緒にファイルに書き込む場合、これはアドレス空間のコピーをファイルにコピーし、読み取り時にそれをコピーして戻すことと同じであり、構造全体の読み取りが完了するのではありませんか? これにより、従来の方法でファイルの内容を解析するなどの問題を考慮する必要がなくなります。
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <Windows.h>
using namespace std;
struct MyStruct
{
int id;
char name[20];
float score;
};
int main()
{
MyStruct myList[3];
myList[0].id = 1;
strcpy_s(myList[0].name, "zhang");
myList[0].score = 60.0;
myList[1].id = 2;
strcpy_s(myList[1].name, "wang");
myList[1].score = 70.0;
fstream myFile("test.txt", ios::out | ios::binary);
myFile.write((char*)myList, sizeof(MyStruct) * 3);//将结构体数组整体写入
myFile.close();
fstream myFileReader("test.txt", ios::binary | ios::in);
memset(myList, '\0', sizeof(MyStruct) * 3);
myFileReader.read((char*)myList, sizeof(MyStruct) * 3);
for (int i=0;i < 3;i++) {
printf("id:%d\n", myList[i].id);
printf("name:%s\n", myList[i].name);
printf("score:%f\n", myList[i].score);
}
}
ファイル全体をメモリからファイルに書き込むには write 関数を使用し、ファイル全体をメモリからメモリに読み取るには read 関数を使用します。
操作結果:
ご覧のとおり、ファイルからのデータの読み取りには問題はありません。
コードでは、構造体配列の最初の 2 つにのみ値を割り当てているため、最後の配列にはデータがありません。しかし、ここにも問題があり、明らかに memset(myList, '\0', sizeof(MyStruct) * 3); を使用して、このメモリ領域にすべての値を 0 に割り当てています。(熱い熱い熱いが虚無に相当するような気がして不思議)
注:ファイルの内容を変更するには、ファイルを直接開いて変更するのではなく、write() メソッドを使用する必要があります。そうしないと、以下に示すようにコードが文字化けします。
理由を考えてみると、データストリームがバイトではなくバイナリで送信されるため、バイトコードレベルで変更するとフォーマットが整わなくなるためだと思います。