Почему функция fgets устарела?

Из учебника по программированию GNU C :

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

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

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

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

(§7.21.7.2)

GNU 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 . Однако я бы не рекомендовал этот кулдж.

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