1

My professor write a C code about fgets,feof with using stdin. But I don't understand how it works.

fgets(list, 100, stdin);

while (!feof(stdin))
{
    printf("feof!");
    
    fgets(list, 100, stdin);
}

when i write a 'hello', function while is working. why feof(stdin) returns 0?

I think first fgets read stdin buffer all of string(include '\0'). therefore I think while shouldn't work because feof(stdin) returns 1 What am i wrong?

Oliver
  • 11
  • 1
  • 3
    [Why is “while( !feof(file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feoffile-always-wrong) – Some programmer dude Dec 10 '22 at 12:10
  • And [`feof`](https://en.cppreference.com/w/c/io/feof) returns "true" (non-zero) when the input file reaches the end. For terminal input through `stdin` that happens when you press the end-of-file keyboard sequence (`Ctrl-D` on Linux or macOS, `Ctrl-Z` on a new line in Windows). – Some programmer dude Dec 10 '22 at 12:13
  • "fgets read stdin buffer all of string(include '\0')" --> No. `fgets()` reads a _line_ (characters up to and including a `'\n'`), saves that to the buffer and then appends a `'\0'`. Now the buffer is a _string_. – chux - Reinstate Monica Dec 10 '22 at 15:11
  • 2
    To make @Someprogrammerdude's comment explicit, your professor's code is wrong. – Nate Eldredge Dec 10 '22 at 16:20
  • Always control your *Read-Loop* with the return from your *Read-Function*... (your professor's implementation is horribly awkward, though not technically incorrect) – David C. Rankin Dec 11 '22 at 03:51

1 Answers1

1

Tip: always check the return value of input functions and most other I/O functions too.

fgets(list, 100, stdin);  // Weak code

Yes, calling printf("feof!"); inside the loop is misleading as the end-of-file indicator for stdin is not set given the prior test condition while (!feof(stdin)).

How to read from stdin with fgets()?

Do not use feof() for this task for primary detection

fgets() returns NULL when:

  1. An end-of-file just occurred in the previous input operation.

  2. An end-of-file had occurred in the some input operations even before that.

  3. An input error just occurred. Examples: file to read is an output stream or a parity error on some serial communication.

while (!feof(stdin)) only detects 1 & 2.

Unless the return value of fgets(list, 100, stdin) is checked, using list may be a problem.

feof() is useful after an I/O function returned the possibility of the need.

Size to the object, avoid magic numbers


Good usage:

char list[100];
while (fgets(list, sizeof list, stdin)) {
  printf("%s", list):
}

if (feof(stdin)) {
  puts("End-of-file");
} else if (ferror(stdin)) {
  puts("Error");
} else {
  puts("Unexpected state");
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256