From The GNU C Programming Tutorial:
The
fgets
("file get string") function is similar to the gets function. This function is deprecated -- that means it is obsolete and it is strongly suggested you do not use it -- because it is dangerous. It is dangerous because if the input data contains a null character, you can't tell. Don't usefgets
unless you know the data cannot contain a null. Don't use it to read files edited by the user because, if the user inserts a null character, you should either handle it properly or print a clear error message. Always usegetline
orgetdelim
instead offgets
if you can.
I thought the fgets
function stops when it encounters a \0
or \n
; why does this manual page suggest a null byte is "dangerous" when fgets
should handle the input properly? Furthermore, what is the difference between getline
and fgets
, and is the fgets
function truly considered deprecated in the C99 or future C standards?
No, fgets
is not actually deprecated in C99 or the current standard, C11. But the author of that tutorial is right that fgets
will not stop when it encounters a NUL, and has no mechanism for reporting its reading of such a character.
The
fgets
function reads at most one less than the number of characters specified byn
from the stream pointed to bystream
into the array pointed to bys
. No additional characters are read after a new-line character (which is retained) or after end-of-file.
(§7.21.7.2)
GNU's getdelim
and getline
have been standardized in POSIX 2008, so if you're targeting a POSIX platform, then it might not be a bad idea to use those instead.
EDIT I thought there was absolutely no safe way to use fgets
in the face of NUL characters, but R.. (see comments) pointed out there is:
char buf[256];
memset(buf, '\n', sizeof(buf)); // fgets will never write a newline
fgets(buf, sizeof(buf), fp);
Now look for the last non-\n
character in buf
. I wouldn't actually recommend this kludge, though.