如何在c中制作二进制文件----结构中的结构



如果我有一个像这样的链表,我该如何制作一个二进制文件:

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,写出jorintchar[],计算材料的数量,写入该数字,然后写入每种材料(floatchar[])的数据。你可以考虑另一种方法,不写材料的数量和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;
}

最新更新