Хорошо, поэтому я предлагаю вам забыть о связанных списках.Просто придерживайтесь первой проблемы: чтение данных из двоичного файла.
В тексте задачи неясно размер объектов, поэтому предположим, что в нем говорится: «Существует двоичный файл, содержащий виджеты, состоящие из 32-разрядного целого числа (little-endian) и 8-разрядногочисло, представляющее символ ASCII. Сбросьте все виджеты до stdout
по одному на строку, представляющую целое число в основании 10, за которым следует пробел, а затем символ ".
Давайте предположим, что ваш int
является 32-разряднымendian, а ваш символ - это байт со знаком, т. е. давайте предположим, что вы находитесь на одной из 99,9% машин в мире.
Теперь вам нужно прочитать виджеты, то есть int и char.Обычно при чтении вам нужно выбрать две функции: fscanf
и fread
.Первый читает данные, отформатированные для чтения человеком, а второй читает байты, как они есть из файла.Какой тебе нужен сейчас?второй, поэтому мы должны использовать это.
В своем коде вы пишете
while (!feof(fptr))
Это всегда неправильно .Единственный правильный способ чтения файла:
while (1) {
// Read
// Check
// Use
}
Тогда вы можете найти способ прочитать и проверить условие while, но, поверьте мне: напишите это так в первый раз.
Итак, давайте заполним выше шаблон.Чтобы проверить, удалось ли fread
, вам нужно проверить, вернул ли он количество элементов, которые вы запрашивали.
while (1) {
int i;
char c;
// Read
int ok1 = fread(&i, 4, 1, fptr);
int ok2 = fread(&c, 1, 1, fptr);
// Check
if (ok1 != 1 || ok2 != 1)
break;
// Use
printf("%d %c\n", i, c);
}
Конечно, вы можете упаковать это во время условия, но я не вижу причины для этого.
Теперь я бы проверил это с вашим вкладом и с хорошимотладчик и проверьте, распечатаны ли все данные в файле.Если все в порядке, вы можете перейти к остальной части проблемы, то есть поместить эти виджеты в связанный список.
Здесь я предположил, что вы еще не изучили struct
с.Если это не так, вы можете работать с ними:
struct widget {
int i;
char c;
};
[...]
while (1) {
struct widget w;
// Read
int ok1 = fread(&w.i, 4, 1, fptr);
int ok2 = fread(&w.c, 1, 1, fptr);
// Check
if (ok1 != 1 || ok2 != 1)
break;
// Use
printf("%d %c\n", w.i, w.c);
}
Не обманывайтесь тем фактом, что виджет имеет такую же структуру ваших данных в файле.Вы не можете поверить, что
fread(&w, 5, 1, fptr); // No! Don't do this
правильно прочитает ваши данные.При создании структуры компилятор может поместить все необходимое пространство между полями, поэтому я не удивлюсь, если sizeof(widget)
вернет 8.
Отказ от ответственности: я написал код прямо в браузереи не проверял!