Чтение строк динамического размера из двоичного файла - PullRequest
1 голос
/ 22 апреля 2011

Скажем, структура файла, который я хочу прочитать, выглядит следующим образом:

typedef struct {
    char length;
    char* text;
} name;
typedef struct {
    long n_names;
    name* names;
} file;

В файле сначала указывается количество имен, за которым следует список имен с динамическими длинами.Поэтому мне нужно выделить память для массива names, но прежде чем я смогу это сделать, мне сначала нужно узнать длину всех имен.

Как мне это решить?

Ответы [ 5 ]

2 голосов
/ 22 апреля 2011

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

Примечаниечто в приведенном выше примере размер sizeof (имя структуры) фиксирован, так как текст является лишь указателем на какое-то другое местоположение.

1 голос
/ 23 апреля 2011

Если у вас есть свободная память, просто выделите размер файла;в противном случае обработайте файл дважды: сначала для суммирования длин (?), а затем для чтения имен.

1 голос
/ 23 апреля 2011

После того, как вы прочитали количество имен (n_names), вы можете malloc достаточно памяти для хранения структур (например, my_file.names = malloc(sizeof(*my_file.names) * my_file.n_names);).

Затем вы можете выполнить итерацию по своему файлу, malloc -ing памяти для каждой строки по очереди, в соответствии с:

for (i = 0; i < my_file.n_names; i++)
{
    int len;
    fread(&len, sizeof(len), 1, fid);
    my_file.names[i].text = malloc(len+1);
    ...
}
1 голос
/ 22 апреля 2011

Это было бы так же, как при подсчете размера строки в памяти вручную. Вы повторяете, пока не достигнете нулевого терминатора, который скажет вам, что вы достигли конца имени. И затем вы делаете это, пока не достигнете EOF.

0 голосов
/ 23 апреля 2011
void readname(struct name* name,FILE* f)
    {
    fread(&name->length,1,1,f);
    name->text = malloc(name->length);
    fread(name->text,name->length,1,f);
    }

readfile аналогично, но второе fread(...); становится for(...) readname(...);

...