fgets(3)
C library function
Reads a line into an array without going past its size, keeps the \n and always terminates the string. Returns NULL at end of file or on error.
#include <stdio.h>
char *fgets(char *restrict s, int n, FILE *restrict stream);Description
fgets reads characters from stream and stores them in s, at most n - 1 of them. It stops after a \n, which it keeps in the array, or at end of file, and always adds a '\0' after the last character read. So it cannot overflow an array whose real size you pass it, which makes it the safe way to read a line. Its old cousin gets, which never knew the size of the array, was removed from the standard in C11.
To read from the keyboard, pass stdin as stream.
Return value
s if at least one character was read. NULL if end of file comes before the first character, or on error. Hence the classic loop: while (fgets(line, sizeof line, stdin) != NULL).
Pitfalls
The
\nstays in the string. To remove it, whatever the length of the line:line[strcspn(line, "\n")] = '\0';.A line longer than the array is cut, and the rest arrives on the next call, as in the example. A missing
\nat the end of the array signals that cut, or a last line with no newline.nmust be the size of the array.sizeof lineworks on an array declared in the function, not on a pointer received as a parameter, which measures only 8 bytes.After a
scanf("%d", &age), the\ntyped after the number stays in the input buffer, and the nextfgetsreads an empty line.
Example
#include <stdio.h>
int main(void){ char line[8];
while (fgets(line, sizeof line, stdin) != NULL) printf("[%s]\n", line); return 0;}$ gcc -Wall -Wextra -g fgets.c -o fgets$ printf "Rabat\nCasablanca\n" | ./fgets[Rabat][Casabla][nca]“Rabat” fits in the array with its \n, which pushes the closing bracket onto the next line. “Casablanca” does not fit: the first call takes 7 characters plus the '\0', the second one gets the rest.
line_reader_repair
Write read_next_line, which reads a descriptor with read and returns one allocated line per call, newline kept as fgets does, then NULL at end of file.