peroksid
peroksid

Reputation: 927

Why EOF is recognized if it is first character in line?

I wrote this C program:

#include <stdio.h>

main()
{
  int numspaces, numtabs, numnl, c;

  while ((c = getchar()) != EOF){
    if (c == ' ') ++numspaces;
    if (c == '\t') ++numtabs;
    if (c == '\n') ++ numnl;
  }
  printf("Spaces:\t\t%d\nTabs:\t\t%d\nNew lines:\t\t%d\n", numspaces, numtabs, numnl);
}

I think this while loop must finish when I press Ctrl+D and "return". It does if Ctrl+D is the first thing I type in a line. But if I start a line with other character (letter, space, tab) and then Ctrl+D and then "return" - the loop continues.

I test this in Mac OS X terminal, I see it echoing ^D and it still continues the loop. What am I missing here?

Upvotes: 3

Views: 521

Answers (3)

AProgrammer
AProgrammer

Reputation: 52294

CTRL-D or more precisely the character set to the VEOF entry of the c_cc field of a termios control structure (stty is the easiest way to query and modify those settings from the command line) is to be interpreted as (quote from the Single Unix Specification V4):

Special character on input, which is recognized if the ICANON flag is set. When received, all the bytes waiting to be read are immediately passed to the process without waiting for a , and the EOF is discarded. Thus, if there are no bytes waiting (that is, the EOF occurred at the beginning of a line), a byte count of zero shall be returned from the read(), representing an end-of-file indication. If ICANON is set, the EOF character shall be discarded when processed.

Thus to send a EOF indication from a terminal you hit CTRL-D once when there is no bytes waiting to be returned (typically at the start of a line), and twice when there are some.

Upvotes: 4

glglgl
glglgl

Reputation: 91049

Ctrl+D terminates the current read() call.

If you already have typed something, this "something" will be read back, and the return value of read() is the length of this "something".

Only if you are at the start of a line, read() will return 0, what is used as an indicator to EOF.

Upvotes: 1

Paul Draper
Paul Draper

Reputation: 83253

If you type something, hit the return key, and then hit Ctrl+D, it will stop.

Ctrl+D will end input to the program, but only if there is nothing left in the terminal's buffer.

FYI, EOF is not really a character. getchar() just returns an integer value EOF (typically -1) when there is nothing left to read.

Also, note that this question only applies to terminals. If you piped it in from a file, things would be behave just as you expect.

Upvotes: 3

Related Questions