2013-05-01 6 views
6

От The GNU C Programming Tutorial: Почему функция fgets устарела?

Функция

fgets ("Файл прибудет строку") похожа на функцию получает . Эта функция устарела - это означает, что она устарела , и настоятельно рекомендуется вам ее не использовать - потому что это опасно. Это опасно, потому что если входные данные содержат нулевой символ , вы не можете сказать. Не используйте fgets, если вы не знаете, что данные не могут содержать нуль. Не используйте его для чтения файлов, отредактированных пользователем , потому что если пользователь вставляет нулевой символ, вы должны либо правильно обработать его, либо распечатать сообщение об ошибке. Всегда используйте getline или getdelim вместо fgets, если можете.

Я думал, что функция fgets останавливается, когда он встречает \0 или \n; почему эта страница руководства предлагает нулевой байт, является «опасным», когда fgets должен правильно обрабатывать вход? Кроме того, в чем разница между getline и fgets и является функцией fgets, которая действительно считается устарела в C99 или будущих стандартов C?

ответ

12

Нет, fgets на самом деле не рекомендуется использовать в C99 или в настоящем стандарте, C11. Но автор этого учебника прав, что fgets не остановится, когда он встретит NUL и не имеет механизма для сообщения о его чтении такого символа.

fgets функция считывает максимум на один меньше, чем количество символов, указанных n из потока, на который указывает stream в массив, на который указывает s. Никакие дополнительные символы не читаются после символа новой строки (который сохраняется) или после окончания файла.

(§7.21.7.2)

ГНУ getdelim и getline были стандартизированы в POSIX 2008, так что, если вы ориентируетесь на POSIX платформе, то она не может быть плохой идеей, чтобы использовать их вместо.

EDIT Я думал, что не было абсолютно никакой безопасный способ использовать fgets в лице символов NUL, но R .. (см комментарии) указал, есть:

char buf[256]; 

memset(buf, '\n', sizeof(buf)); // fgets will never write a newline 
fgets(buf, sizeof(buf), fp); 

Теперь посмотрим на последний не \n знак в buf. Однако я бы не рекомендовал этот кулдж.

+0

Так что 'fgets' продолжает читать прошлые пустые байты, ища только символ новой строки? –

+1

@VilhelmGray: это правильно, и это не скажет вам, что так оно и было. Невозможно убедиться, что первый «\ 0», который вы нашли, был добавлен 'fgets' или нет. –

+4

нулевые байты не принадлежат к ** текстовым ** файлам.'fgets()' был разработан для работы с текстовыми файлами: использование 'fgets()' с файлами двоичных данных не рекомендуется. – pmg

5

Это просто пропаганда GNU. В официальном смысле fgets не рекомендуется. gets однако опасен и устарел.

+3

'get' был фактически удален * от стандарта ISO C 2011 года. (Он не был официально устарел или устарел на C99.) –

+3

@ KeithThompson: Раздел 7.26.9 ISO/IEC 9899: 1999 TC3 говорит: «Функция' gets' устарела и устарела ». поэтому я считаю, что 'get' официально устарел на C99. –

+0

Был ли этот язык добавлен в один из TC, или он был в оригинальной публикации C99? –

Смежные вопросы