Чтение неизвестного количества структур из файла - C
Автор вопроса: karomaОтветов: 5
У меня возникли проблемы с тем, чтобы моя программа считывала данные из файла. Проблема в том, что файл в настоящее время пуст. Каждый раз, когда программа запускается, один массив books[] будет заполняться и записываться в файл позже в коде. Хотя я уверен, что это будет работать, когда все 10 структур находятся в файле, на данный момент происходит сбой, так как файл пуст и он пытается прочитать 10 структур.
Есть ли способ прочитать неизвестное количество структур (до 10) из файла?
struct stock
{
char name[31];
int stock;
};
int main (void)
{
stock books[10];
FILE *fptr;
fptr = fopen("stock.dat", "rb");
fread(books, sizeof(struct stock), 10, fptr);
fclose (fptr);
}
где вылетает? в чем ошибка? это сводящее с ума почти полное описание проблемы. tbert 23.03.2012
Если вы контролируете формат файла (т. е. он не определен кем-то другим), я рекомендую использовать текстовый формат (например, имя, по одному на строку) вместо двоичного. Это будет означать немного больше кода, но вы пишете код только один раз; файл будет намного удобнее. William Morris 23.03.2012
Вам нужно проверить значение, возвращаемое fopen, чтобы убедиться, что файл существует.
Вам нужно проверить количество прочитанных элементов - значение size_t, возвращаемое fread
Ответ 3 · рейтинг 1 · paxdiablo
Сбой? Надеюсь, не те утверждения, если только файла там нет вообще. Это может привести к сбою, если вы предполагаете, что в вашем массиве есть десять допустимых элементов, поскольку поля name, вероятно, не будут допустимыми строками C.
Способ, которым вы определяете, сколько вы на самом деле читаете, заключается в следующем:
num = fread(books, sizeof(struct stock), 10, fptr);
хотя я бы предпочел:
num = fread (book, sizeof(*book), sizeof(book) / sizeof(*book), fptr);
поскольку это означает, что вам не нужно менять много кода в случае изменения имени типа или размера массива.
Если возможно, что файл даже не открывается, вам также необходимо проверить возвращаемое значение fopen. Полный код будет выглядеть примерно так:
#include <stdio.h>
typedef struct {
char name[31];
int stock;
} tStock;
int main (void) {
tStock book[10];
size_t num, i;
FILE *fptr = fopen ("stock.dat", "rb");
if (fptr == NULL) {
num = 0;
} else {
num = fread (book, sizeof(*book), sizeof(book) / sizeof(*book), fptr);
fclose (fptr);
}
printf ("Read %d items\n", num);
for (i = 0; i < num; i++) {
printf (" Item %d is %s, %d\n", book[i].name, book[i].stock);
}
return 0;
}
Ответ 4 · Ed Heal
Код выглядит нормально (хотя еще не пробовал). См. fread справочную страницу - она возвращает количество прочитанных элементов.
Ответ 5 · Israel Unterman
Я не уверен, но fread() не должен вызывать сбой, а должен возвращать количество прочитанных элементов, которое в данном случае равно 0. Также я не совсем понимаю, как компилируется строка stock books[10];, она должна быть struct stock books[10];.
Я бы предложил две вещи: 1. заменить на struct stock books[10]; 2. Важно проверить, что fptr не равен NULL. Возможно, он не смог открыть файл (возможно, не в том же каталоге или еще не существует), что приводит к NULL fptr, и использование его в fread приведет к сбою приложения.