What happens when fgets encounters EOF in the middle of input?

The manual page says:

fgets () returns s on success, and NULL on error or when the end of the file occurs when characters were not read.

I wrote a small C file that calls fgets to test its behavior. I especially wanted to see what happens when EOF happens after typing some characters. I used the eof key combination (Ctrl + D) on bash. I had to press Ctrl + D twice to return fgets. He printed the entered characters until I pressed Ctrl + D twice. Pressing Ctrl + D once after entering some characters had no effect. If after that I entered some characters, they were stored in the transferred array. Why do feaks behave this way?

+4
source share
3 answers

The behavior you describe has nothing to do with fgets. The shell does not close the input stream until you press ctrl-D a second time.

+6
source

You should find that if the input ends after reading at least some characters, but before meeting a new line, that fgets returns non-null (a pointer to the provided buffer), and the supplied buffer will not contain a new line but will be completed with a zero value.

This is exactly what the documentation for fgets says.

eg.

 #include <stdio.h> int main(void) { char buffer[200]; char* ret = fgets(buffer, sizeof buffer, stdin); printf("exit code = %p\n", (void*)ret); if (ret != 0) { printf("read code = %s<--END\n", buffer); } return 0; } 

output:

 $ printf "no newline here->" | ./a.out exit code = 0x7fff6ab096c0 read code = no newline here-><--END 

or

 $ printf "newline here->\nmore text\n" | ./a.out exit code = 0x7fff6f59e330 read code = newline here-> <--END 

without input:

 $ printf "" | ./a.out exit code = (nil) 
+4
source

It is just like reading from a text file stored on a disk that does not have a newline at the end of the last line. Description The C-standard description of fgets() indicates what it does, including in this case:

char *fgets(char * restrict s, int n, FILE * restrict stream);

The fgets function reads no more than one than the number of characters specified by n from the stream pointed to by the stream to the array pointed to by s . No additional characters are read after the newline character (which is saved) or after the end of the file. the null character is written immediately after the last read character to the array.

fgets() can give you a line without a new line if the input line is too long, or if there is no new line before the end of the file.

When you read a file from disk, the condition for ending the file occurs when you reach the end of the file. When you read from an interactive device, such as a keyboard, the way that the end-of-file condition is triggered is not specified by the C standard. On Unix-like systems, it is started by typing Control-D at the beginning of a line or by typing Control-D twice in the middle of a line ( although the control character can be reconfigured).

Is it possible that this is possible depends on the implementation.

C99 7.19p2 says:

A text stream is an ordered sequence of characters composed in a line, each line consisting of zero or more characters plus the end of a newline character. Whether the last line requires a trailing newline is determined by the implementation.

Unix-like systems generally do not need a trailing newline.

+2
source

Source: https://habr.com/ru/post/1390975/


All Articles