Search code examples
cwindowseofgetchar

Does getchar read ctrl+z or return EOF?


I have this code:

#include <stdio.h>

int main(void) {

int d=0;

d = getchar();
printf("%d\n", d);

}

Output:

^Z
-1

From what I understand there are two things that could be happening here:

  1. Getchar reads ctrl+z and it returns it.
  2. Getchar reads nothing and returns EOF.

Are there any more possibilities?, which of the two is correct?


Solution

  • There are two parts to this:

    1. What getchar() does.
    2. What the console/OS/run-time environment does.

    What getchar() does is clear:

    Returns EOF (-1) on any failure. If the failure is caused by end-of-file additionally sets the eof indicator (see feof() on stdin).

    What the OS console does in this case (Windows):

    1. Receive input Ctrl-Z (non- printing ASCII control character 26)
    2. Echoes non-printing Ctrl-Z as ^Z
    3. Traps Ctrl-Z as EOF and inserts EOF into stdin (not Chr.26).

    Noting that Ctrl-Z (SUB) is peculiar to Windows, MS-DOS and before that CP/M. In CP/M SUB was used to pad files to a multiple of 128 bytes (a requirement of its primitive filesystem), so for files that are not a multiple 128 bytes it essentially marked the end-of-file. On Unix and Linux Ctrl-D (EOT - end-of-transmission) is used which arguably makes more sense, but neither is truly an end-of-file, the terminology comes from treating stdin as a "file" stream, which simplifies device driver interfaces and redirection.

    So in summary, the system (Windows) treats Ctrl-Z in the console as an instruction to insert an EOF into the console input stream, and getchar() returns EOF, and sets the input stream's EOF flag. The echoing of ^Z (or any character) is a platform specific side-effect. getchar() does not in fact echo anything.

    It is not truly the end of the stream, and input can resume after calling one of rewind(), fsetpos(), fseek(), or clearerr().

    Note also that this is strictly behaviour of the console input stream. If stdin were redirected from a file , EOF would be indicated at the true end-of-file, and that file could contain Ctrl-Z (SUB) characters, and these would be returned by getchar() as value 26.