Вопрос по fread, c, fwrite – fread'ing и fwrite'ing структура, содержащая указатели [дубликаты]

0

This question already has an answer here:

Writing and reading (fwrite - fread) structures with pointers 3 answers
gcc (GCC) 4.7.0
c89

Привет,

У меня есть следующая структура, которую я пытаюсь написать и переписать.

Однако, потому что мое устройство и ресурс являются указателями. 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;
}
& quot; Это не будет работать & quot; -- почему бы и нет? Kerrek SB

Ваш Ответ

3   ответа
1

Еслиdevice а такжеresource может иметь переменную длину, вы должны записать размерdevice а затем данные. Сделать то же самое дляresource. When you read them back you can read the size, then allocate memory and finally read the value.

1

кажется, ответили на свой вопрос, fread и fwrite, просто посмотрите на то, что находится в памяти, и поместите это в файл. Это прекрасно работает, если вы пишете вещи, которые не имеют указателей (например, большие массивы чисел). Он не предназначен для написания структур с указателями.

Если этот файл имеет формат, вам нужно сделать то, что говорит формат. Если вы создаете формат по ходу дела, то вы должны записать каждого участника по одному в файл. Вам понадобится какой-то буфер для чтения (вам может понадобиться изменить его размер, если у вас нет спецификации максимальной длины). Кроме того, ваша функция database_write также должна быть немного изменена.

1

Может быть, вы можете использовать поле для длины устройства и ресурса в вашей структуре "struct data". Создайте оболочку для fread () и fwrite (), которая читает / записывает эту длину. В этой оболочке вы можете использовать устройства memcpy, ресурс во временном буфере и использовать на нем функцию fwrite ().

Это простое и очень простое решение.

При отправке пакетов в сети вы обычно видите структуры, содержащие указатели на символы. Первые 4/8 байтов хранят длину данных, а остальные байты содержат фактические данные. Пользователь, читающий пакет, сначала читает начальные 4/8 байтов. В зависимости от этого вызывается read () для чтения оставшихся данных.

Вы можете сослаться Является ли "структура взломать" технически неопределенное поведение?

Похожие вопросы