End of File (EOF) in C

c eof
newbie picture newbie · Dec 5, 2010 · Viewed 363.6k times · Source

I am currently reading the book C Programming Language by Ritchie & Kernighan. And I am pretty confused about the usage of EOF in the getchar() function.

First, I want to know why the value of EOF is -1 and why the value of getchar()!=EOF is 0. Pardon me for my question but I really don't understand. I really tried but I can't.

Then I tried to run the example on the book that can count the number of characters using the code below but it seems that I never get out of the loop even if I press enter so I am wondering when would I reach the EOF?

main(){
   long nc;
   nc = 0;
   while (getchar() != EOF)
       ++nc;
   printf("%ld\n", nc);
}

Then, I read the same problem at Problem with EOF in C. Most people advised that instead of using EOF, use the terminator \n or the null terminator '\0' which makes a lot of sense.

Does it mean that the example on the book serves another purpose?

Answer

Steve Jessop picture Steve Jessop · Dec 5, 2010

EOF indicates "end of file". A newline (which is what happens when you press enter) isn't the end of a file, it's the end of a line, so a newline doesn't terminate this loop.

The code isn't wrong[*], it just doesn't do what you seem to expect. It reads to the end of the input, but you seem to want to read only to the end of a line.

The value of EOF is -1 because it has to be different from any return value from getchar that is an actual character. So getchar returns any character value as an unsigned char, converted to int, which will therefore be non-negative.

If you're typing at the terminal and you want to provoke an end-of-file, use CTRL-D (unix-style systems) or CTRL-Z (Windows). Then after all the input has been read, getchar() will return EOF, and hence getchar() != EOF will be false, and the loop will terminate.

[*] well, it has undefined behavior if the input is more than LONG_MAX characters due to integer overflow, but we can probably forgive that in a simple example.