Нет необходимости открывать файл более одного раза или проходить через него более одного раза.
Посмотрите на функцию POSIX getline()
. Он читает строки в выделенном пространстве. Вы можете использовать его для чтения строк, а затем скопировать результаты для связанного списка.
Нет необходимости в связанном списке, чтобы знать, сколько строк впереди; это преимущество списков.
Итак, код может быть выполнен за один проход. Даже если вы не можете использовать getline()
, вы можете использовать fgets()
и следить за тем, читает ли он каждый раз до конца строки, а если нет, вы можете выделить (и перераспределить) пространство для хранения строки по мере необходимости ( malloc()
, realloc()
и в конечном итоге free()
из <stdlib.h>
).
Ваши конкретные вопросы в значительной степени несущественны, если вы используете какой-либо подход, который я предлагаю, но:
Использование fseek()
(и в крайнем случае rewind()
) переместит указатель чтения (для fgetc()
и всех других функций), если «файл» не поддерживает поиск (например, канал, предоставленный как стандартный ввод).
Символы могут быть определены с помощью stat()
или fstat()
или их вариантов. Строки не могут быть определены, кроме как путем чтения файла.
Поскольку размер файла может варьироваться от нуля до гигабайта, разумного способа распределения фиксированного размера не существует. Вы в значительной степени вынуждены динамически распределять память с помощью malloc()
et al. (За кадром getline()
использует malloc()
и realloc()
.)