| FGETS(3) | Library Functions Manual | FGETS(3) |
fgets — get a line
from a stream
#include
<stdio.h>
char *
fgets(char
*str, int size,
FILE *stream);
The
fgets()
function reads at most size-1 characters from the
given stream and stores them in the string
str. Reading stops when a newline character is found,
at end-of-file, on error, or after size-1 bytes are
read. The newline, if any, is retained. The string will be NUL-terminated if
fgets() succeeds; otherwise the contents of
str are undefined.
Upon successful completion, fgets()
returns a pointer to the string. If end-of-file or an error occurs before
any characters are read, it returns NULL. The
fgets() function does not distinguish between
end-of-file and error, and callers must use
feof(3) and
ferror(3) to determine which
occurred. Whether fgets() can possibly fail with a
size argument of 1 is implementation-dependent. On
OpenBSD, fgets() will never
return NULL when size is
1.
EBADF]EINVAL]The function fgets() may also fail and set
errno for any of the errors specified for the routines
fflush(3),
fstat(2),
read(2), or
malloc(3).
The function fgets() conforms to
ANSI X3.159-1989
(“ANSI C89”).
The function fgets() first appeared in
Version 7 AT&T UNIX.
The following bit of code illustrates a case where the programmer assumes a string is too long if it does not contain a newline:
char buf[1024], *p;
while (fgets(buf, sizeof(buf), fp) != NULL) {
if ((p = strchr(buf, '\n')) == NULL) {
fprintf(stderr, "input line too long.\n");
exit(1);
}
*p = '\0';
printf("%s\n", buf);
}
While the error would be true if a line > 1023 characters were read, it would be false in two other cases:
fgets() will not contain a newline either. Thus
strchr() will return NULL
and the program will terminate, even if the line was valid.strchr(),
correctly assume the end of the string is represented by a NUL
(‘\0’) character. If the first character of a line returned
by fgets() were NUL,
strchr() would immediately return without
considering the rest of the returned text which may indeed include a
newline.Consider using getline(3) instead when dealing with untrusted input.
It is erroneous to assume that fgets()
never returns an empty string when successful. If a line starts with the NUL
character, fgets will store the NUL and continue reading until it encounters
a newline or end-of-file. This will result in an empty string being
returned. The following bit of code illustrates a case where the programmer
assumes the string cannot be zero length.
char buf[1024];
if (fgets(buf, sizeof(buf), fp) != NULL) {
/* WRONG */
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
}
If strlen() returns 0, the index into the
buffer becomes -1. One way to concisely and correctly trim a newline is
shown below.
char buf[1024]; if (fgets(buf, sizeof(buf), fp) != NULL) buf[strcspn(buf, "\n")] = '\0';
| December 1, 2017 | openbsd |