0
gcc (GCC) 4.7.0
c89

你好,

我有以下结构,我正在尝试 fwrite 和 fread。

但是,因为我的设备和资源是指针。fwrite 将读取指针值而不是数据。我不能为设备或资源使用数组。只有指针,因为它们必须动态分配。

我在写之前为结构元素分配了所有内存。此处未显示,因为我想保持片段简短。也不是自由的。

在我的 fread 函数中,我为设备和资源分配内存,以便 fread 读入这些内存位置。但是,这行不通。

做这个的最好方式是什么?

非常感谢您的任何建议,

struct data {
    int id;
    int set;
    char *device;
    char *resource;
};

struct database {
    struct data **db_data;
    size_t database_rows;
    size_t database_data_size;
};

int database_write(FILE *fp, const struct database *db)
{
    rewind(fp);

    if(fwrite(*db->db_data, sizeof(struct data), 1, fp) == -1) {
        return DATABASE_ERROR;
    }

    return 0;
}

struct database* database_read(FILE *fp, size_t db_rows, size_t db_data_size)
{
    struct database *db = NULL;
    size_t i = 0;

    db = malloc(sizeof(struct database));

    db->database_rows = db_rows;
    db->database_data_size = db_data_size;
    db->db_data = malloc(sizeof(struct data) * db_rows);

    for(i = 0; i < db_rows; i++) {
        db->db_data[i] = malloc(sizeof(struct data));
        db->db_data[i]->device = malloc(db_data_size);
        db->db_data[i]->resource = malloc(db_data_size);
    }

    rewind(fp);

    if(fread(*db->db_data, sizeof(struct data), 1, fp) == -1) {
        return NULL;
    }

    return db;
}
4

3 回答 3

1

您似乎已经回答了自己的问题, fread 和 fwrite 只需查看内存中的内容并将其放入文件中。如果您正在编写没有指针的东西(例如大数字数组),这非常有用。它不是为编写带有指针的结构而设计的。

如果这个文件有格式,你需要按照格式说的做。如果您正在制定一种格式,那么您应该将每个成员一个一个地写入文件中。您将需要某种缓冲区来读入(如果您没有最大长度规范,您可能需要调整它的大小)。此外,您的 database_write 函数也需要进行相当多的更改。

于 2012-09-25T10:45:01.917 回答
1

如果device并且resource可以具有可变长度,则应先记下数据的大小,device然后再记下数据。对 做同样的事情resource。当你读回它们时,你可以读取大小,然后分配内存,最后读取值。

于 2012-09-25T10:47:41.533 回答
1

你自己描述了你的问题。fwrite 将写入地址而不是值。

可能您可以在结构“结构数据”中使用一个字段来表示设备和资源的长度。为读取/写入此长度的 fread() 和 fwrite() 创建一个包装器。在这个包装器中,您可以 memcpy 设备、临时缓冲区中的资源并在其上使用 fwrite()。

这是一个简单且非常基本的解决方案。

在网络中发送数据包时,您通常会看到一个包含 char 指针的结构。前 4/8 个字节存储数据的长度,其余字节包含实际数据。用户读取数据包,首先读取开始的 4/8 字节。根据此,发出 read() 调用以读取剩余数据。

您可以参考 “结构黑客”技术上未定义的行为吗?

于 2012-09-25T10:52:01.537 回答