Representing EOF in C code?

No. EOF is not a character, but a state of the filehandle.

While there are there are control characters in the ASCII charset that represents the end of the data, these are not used to signal the end of files in general. For example EOT (^D) which in some cases almost signals the same.

When the standard C library uses signed integer to return characters and uses -1 for end of file, this is actually just the signal to indicate than an error happened. I don't have the C standard available, but to quote SUSv3:

If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream shall be set and fgetc() shall return EOF. If a read error occurs, the error indicator for the stream shall be set, fgetc() shall return EOF, and shall set errno to indicate the error.


EOF is not a character (in most modern operating systems). It is simply a condition that applies to a file stream when the end of the stream is reached. The confusion arises because a user may signal EOF for console input by typing a special character (e.g Control-D in Unix, Linux, et al), but this character is not seen by the running program, it is caught by the operating system which in turn signals EOF to the process.

Note: in some very old operating systems EOF was a character, e.g. Control-Z in CP/M, but this was a crude hack to avoid the overhead of maintaining actual file lengths in file system directories.


EOF is not a character. It can't be: A (binary) file can contain any character. Assume you have a file with ever-increasing bytes, going 0 1 2 3 ... 255 and once again 0 1 ... 255, for a total of 512 bytes. Whichever one of those 256 possible bytes you deem EOF, the file will be cut short.

That's why getchar() et al. return an int. The range of possible return values are those that a char can have, plus a genuine int value EOF (defined in stdio.h). That's also why converting the return value to a char before checking for EOF will not work.

Note that some protocols have "EOF" "characters." ASCII has "End of Text", "End of Transmission", "End of Transmission Block" and "End of Medium". Other answers have mentioned old OS'es. I myself input ^D on Linux and ^Z on Windows consoles to stop giving programs input. (But files read via pipes can have ^D and ^Z characters anywhere and only signal EOF when they run out of bytes.) C strings are terminated with the '\0' character, but that also means they cannot contain the character '\0'. That's why all C non-string data functions work using a char array (to contain the data) and a size_t (to know where the data ends).

Edit: The C99 standard §7.19.1.3 states:

The macros are [...]
EOF
which expands to an integer constant expression, with type int and a negative value, that is returned by several functions to indicate end-of-file, that is, no more input from a stream;