Семантика fgets()
довольно прямолинейна: считывайте байты из указателя потока FILE*
до тех пор, пока:
- целевой массив заполнен (прочитано и сохранено
n-1
байт).
- новая строка была прочитана из потока и сохранена в целевом массиве.
- достигнут конец файла или произошла ошибка чтения (
EOF
было возвращено вызовом fgetc()
или эквивалентным). условия конца файла и ошибки чтения можно отличить, вызвав ferr()
и/или feof()
после того, как fgets()
вернет NULL
.
Нулевой терминатор всегда сохраняется в массиве после считывания байтов из потока, если только конец файла не был достигнут немедленно (fgets()
возвращает NULL
) или если размер буфера указан равным 0.
fgets()
ведет себя так, как если бы поток считывался по одному байту за раз с помощью fgetc()
.
fgets()
потребляет байты, считанные из потока, и сохраняет их в целевой массив. Он не может прочитать одни и те же байты снова, если вы явно не выполните поиск в обратном направлении в потоке с помощью rewind()
, fseek()
или fsetpos()
, если поток вообще поддерживает поиск. Потоки, прикрепленные к обычным файлам, обычно поддерживают поиск, но файлы, открытые в текстовом режиме, требуют специальной обработки в некоторых системах, особенно в Microsoft Windows. Также обратите внимание, что байт, возвращенный в поток с помощью ungetc()
, будет прочитан с помощью fgets()
перед любыми байтами из фактического потока.
fgets()
сохраняет символ новой строки в целевом массиве, если строка была достаточно короткой, чтобы поместиться в массиве перед нулевым ограничителем.
fgets()
разбивает длинные строки на более мелкие фрагменты, если строка превышает доступное место в целевом массиве. Обработка длинных строк сложна и подвержена ошибкам. Обратите внимание, что когда fgets()
читает неполную строку из-за нехватки места в целевом массиве, следующий вызов fgets()
продолжит чтение с той же строки в точке, где остановился предыдущий вызов.
Если при возврате из fgets()
целевой массив не заканчивается новой строкой, произошло одно из следующих событий:
- текущая строка была слишком длинной, и из потока было прочитано ровно столько байтов, сколько уместилось в массиве.
- прочитанная строка была последней в файле, и файл не заканчивается последовательностью новой строки.
- из файла был прочитан нулевой байт.
Неправильное обращение с этими случаями может привести к потенциальному неопределенному поведению и/или уязвимостям, которые можно использовать.
person
chqrlie
schedule
20.03.2017
fgets()
сделал то же самое, это сломало бы каждую программу C, которая его использует. - person Jonathan Leffler   schedule 20.03.2017rewind
илиfseek
. Прочитайте справочные страницы для fgets, rewind, fseek и т. д. Или посмотрите, можете ли вы найти достаточно подробное руководство по доступу к файлам/потокам на C. Глава C IO в Викиучебнике может быть хорошим началом. - person   schedule 20.03.2017'\n'
). - person M.M   schedule 20.03.2017