如果我有一个像这样的链表,我该如何制作一个二进制文件:
typedef struct jor JOR;
typedef struct materials MATERIALS;
struct jor {
int Number;
char Date[20];
MATERIALS *m;
struct jor *next;
};
struct materials{
float Qty;
char Unit[20];
struct materials *next;
};
如果你的结构是无指针的,你可以使用fwrite
调用并传递一个指向结构的指针。但是,由于结构体中包含指针,因此需要包含用于读取和写入数据的特殊处理。
您可能想要编写一个函数,遍看每个jor
,写出jor
的int
和char[]
,计算材料的数量,写入该数字,然后写入每种材料(float
和char[]
)的数据。你可以考虑另一种方法,不写材料的数量和jor
条目,但只写数字可能会简单得多。
未经测试,但您可能会这样做(我假设您的链表以NULL指针终止):
void WriteData(char[] szFilename, JOR* first)
{
// Open binary file for writing (TODO: check successfully opened)
FILE* fp = fopen(szFilename, "wb");
// Count the number of `JOR`
int i = 0; for (JOR* j = first; j != NULL; j = j->next;) i++;
// Write the count to file
fwrite(&i, sizeof(int), 1, fp);
for (JOR* j = first; j != NULL; j = j->next)
{
// Write contents of `JOR`
fwrite(j, sizeof(int) + sizeof(char)*20, 1, fp);
// Count the number of `MATERIAL`
int k = 0; for (MATERIAL* m = j->m; m != NULL; m = m->next) k++;
// Write the materials to file
fwrite(&k, sizeof(int), 1, fp);
for (MATERIAL* m = j->m; m != NULL; m = m->next)
{
// Write contents of material
fwrite(m, sizeof(float) + sizeof(char)*20, 1, fp);
}
}
fclose(fp);
}
那么对于阅读,你可以这样做:
JOR* ReadData(char[] szFilename)
{
// Open data file (todo: check opened)
FILE* fp = fopen(szFilename, "rb");
// Read number of entries (todo: check read)
int s; fread(&s, sizeof(int), 1, fp);
// Reserve memory for JOR entries (todo: check malloced)
JOR* first = malloc(s*sizeof(JOR));
for (int i = 0; i < s; ++i)
{
// Read most of JOR
fread(first+i, sizeof(int) + sizeof(char)*20, 1, fp);
// Read number of materials in current JOR
int d; fread(&s, sizeof(int), 1, fp);
MATERIAL* m = malloc(d*sizeof(MATERIAL));
for (int j = 0; j < d; ++j)
{
// Read most of MATERIAL
fread(m+j, sizeof(float) + sizeof(char)*20, 1, fp);
// Set next material
m[j].next = m+j+1;
}
first[i].m = m;
// Set next JOR
first[i].next = first+i+1;
}
fclose(fp);
return first;
}