Does fgets() always terminate the char buffer with \0 even if EOF is already reached? It looks like it does (it certainly does in the implementation presented in the ANSI K&R book), but I thought I would ask to be sure.
I guess this question applies to other similar functions such as gets().
EDIT: I know that \0 is appended during "normal" circumstances, my question is targeted at EOF or error conditions. For example:
FILE *fp;
char b[128];
/* ... */
if (feof(fp)) {
/* is \0 appended after EACH of these calls? */
fgets(b, 128, fp);
fgets(b, 128, fp);
fgets(b, 128, fp);
}
The fgets() function stores the result in string and adds a NULL character (\0) to the end of the string. The string includes the newline character, if read. The fgets() function is not supported for files opened with type=record or type=blocked .
fgets terminates at the newline character but appends it at the end of the string str . The function also appends the terminating null character at the end of the passed string.
The fgets() function stores the result in string and adds a null character (\0) to the end of the string. The string includes the new-line character, if read.
If the end of file is reached without reading any characters, fgets is obliged to return NULL .
fgets
does always add a '\0' to the read buffer, it reads at most size - 1
characters from the stream (size
being the second parameter) because of this.
Never use gets
as you can never guarantee that it won't overflow any buffer that you give it, so while it technically does always terminate the read string this doesn't actually help.
Never use gets!!
7.19.7.2 The fgets function Synopsis 1 #include <stdio.h> char *fgets(char * restrict s, int n, FILE * restrict stream); Description 2 The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array. Returns 3 The fgets function returns s if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned.
So, yes, when fgets()
does not return NULL the destination array always has a null character.
If fgets()
returns NULL, the destination array may have been changed and may not have a null character. Never rely on the array after getting NULL from fgets()
.
Edit example added
$ cat fgets_error.c #include <stdio.h> void print_buf(char *buf, size_t len) { int k; printf("%02X", buf[0]); for (k=1; k<len; k++) printf(" %02X", buf[k]); } int main(void) { char buf[3] = {1, 1, 1}; char *r; printf("Enter CTRL+D: "); fflush(stdout); r = fgets(buf, sizeof buf, stdin); printf("\nfgets returned %p, buf has [", (void*)r); print_buf(buf, sizeof buf); printf("]\n"); return 0; } $ ./a.out Enter CTRL+D: fgets returned (nil), buf has [01 01 01] $
See? no NUL in buf :)
man fgets:
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a new‐line is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With