2

It's a basic question.. but had to ask. For a program like this, if the use case is 123^Z, the program doesnt terminate, even though i put an EOF at the end (Ctrl+Z). Why is that so? It's only when I put an EOF after a CR that it works. Any anwers will be appreciated. Thanks.

#include < stdio.h>

void main()
{
    int i, nc;

    nc = 0;
    i = getchar();
    while (i != EOF) {
        nc = nc + 1;
        i = getchar();
    }
    printf("Number of characters in file = %d\n", nc);
}
0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
Iceman
  • 4,202
  • 7
  • 26
  • 39
  • 1
    What platform? The `^Z` makes me think Windows, but it'd be nice if you tagged the question with your platform. Thanks. – sarnold Mar 20 '12 at 22:37
  • What happens if you put a CR after an EOF? – asaelr Mar 20 '12 at 22:53
  • Same behaviour under linux with `^D`. Works only if on newline – paul Mar 20 '12 at 22:53
  • 1
    The short answer is that it's just how Windows works. Note, however, that if you press F6 instead of ctrl+Z, it'll take effect even if it's in the middle of the line. – Jerry Coffin Mar 20 '12 at 22:55
  • possible duplicate of [k&R,how getchar read EOF](http://stackoverflow.com/questions/5473190/kr-how-getchar-read-eof) – LihO Mar 20 '12 at 22:57

1 Answers1

7

In Windows, the Ctrl-Z shortcut will only take effect if it's pressed at the start of a line. Otherwise, the OS ignores it. You must press "enter" or "return" to insert a newline character first.

In Unix, the Ctrl-D shortcut will flush stdin immediately (as mentioned in the below comments), but will not cause getchar() to return EOF unless you are on a new, blank line; same as in Windows.

From the comments (below):

There is no "EOF character" on Unix. An EOF is simply a zero-length read. It happens at the end of ordinary files, and can be forced on a terminal by pressing the control character that's been setup in the terminal settings for EOF (usually ^D). The reason ^D "doesn't work" when the terminal buffer is non-empty is that it doesn't actually insert something in the stream; it just causes the pending read to return, but since the input length is nonzero, it's not treated as an "EOF" by the application.

This addresses a good point - no file actually contains EOF - and pressing Ctrl-D won't "insert" (as I had previously said) anything into the stdin stream. It just flushes stdin. EOF is a standard macro representing a notification that the end of the file was reached by a standard function.

Thanks to @R. for the explanation about EOF.

Chris Browne
  • 1,582
  • 3
  • 15
  • 33
  • 1
    Not quite. While `^D` works within a line to flush STDIN, it doesn't *close* STDIN right away. – Niklas B. Mar 20 '12 at 22:54
  • My system (Debian, admitedly not Unix), doesn't behave like you describe. Typing Ctrl+D in the middle of the line has the apparent effect of typing enter without the enter. – pmg Mar 20 '12 at 22:58
  • Thanks for the comment, Niklas. I updated my answer accordingly. – Chris Browne Mar 20 '12 at 23:48
  • 1
    There is no "EOF character" on Unix. An EOF is simply a zero-length read. It happens at the end of ordinary files, and can be forced on a terminal by pressing the control character that's been setup in the terminal settings for EOF (usually ^D). The reason ^D "doesn't work" when the terminal buffer is non-empty is that it doesn't actually insert something in the stream; it just causes the pending read to return, but since the input length is nonzero, it's not treated as an "EOF" by the application. – R.. GitHub STOP HELPING ICE Mar 21 '12 at 00:26