Files & I/O

end-of-file (EOF)

/ EOF -> EE-oh-EFF /

You are reading a stack of pages one at a time. Eventually you reach for the next page and there is no next page - you have hit the bottom of the stack. End-of-file is exactly that moment: there is no more data to read, and you need a clear, reliable signal so you know to stop rather than spin forever.

Concretely, EOF is not a special byte stored in the file - it is a condition the read interface reports. At the raw level, read(fd, buf, n) returns 0 to mean end-of-file: zero bytes were read and there are no more to come. (A return of -1 is an error, which is different; 0 specifically means EOF.) So the standard loop reads until read() returns 0. At the buffered stdio level, functions like fgetc() return the special value EOF (a macro, conventionally -1, which is why fgetc returns int and not char - so it can carry both every possible byte 0 to 255 and the distinct EOF marker). After a stream hits end-of-file you can confirm it with feof(stream), but note feof reports a past event - it becomes true only after a read has already failed to get data, so you check it after the read, never before, or you risk an extra bogus iteration.

Why it matters: detecting EOF correctly is what separates a loop that processes a whole file from one that runs forever or stops one item early. The classic beginner bug is using feof() as the loop condition at the top - while (!feof(f)) - which reads one time too many because feof only flips after the failed read. The robust pattern is to make the read itself the test: keep going while fgetc returns something other than EOF, or while read returns more than 0.

int c; while ((c = fgetc(f)) != EOF) { putchar(c); /* process one byte */ } /* loop ends exactly when there is no more data - no extra iteration */

Make the read the test. fgetc returns int so EOF (-1) cannot collide with a real byte.

EOF is a condition, not a byte in the file. read() returning 0 is EOF; -1 is an error - keep them separate. And do NOT loop on while (!feof(f)): feof reports a past failed read, so it runs the body one extra time. Test the read's result directly.

Also called
end of fileend-of-input檔案結尾輸入結尾