Search code examples
c++eofcinistreamistream-iterator

istream_iterator ignoring EOF (Ctrl+D) when reading chars


I'm trying to use istream_iterator for reading characters from cin. I've read that pressing Ctrl+D sends an EOF character which ends the input stream. Unfortunately, something is going wrong with it. Here's my code:

#include <iterator>
int main()
{
  using namespace std;

  istream_iterator<char> it(cin), eos;
  while (it != eos) clog << *(it++);
}

I'm running it and typing: as df, then pressing Ctrl+D. It outputs only asd without the last f and then hangs waiting for input. When I type gh and press Ctrl+D again, it prints the remaining f at last, and the g from next input, but again without the last h. And when I finally press Ctrl+D without typing anything, it prints the remaining h and exits.

I expected it to read asdf and exit, since I already pressed Ctrl+D at the end of this first sequence.

Why is it still waiting for input after getting EOF?
Why it doesn't print the last character read before EOF?
And why it exits only when I press Ctrl+D without typing anything before?
How does this loop need to change to make it behave in the way I expect? (i.e. stop reading immediately after getting Ctrl+D sequence in the input, no matter I typed anything before or not, and reading all characters up to the EOF).


Solution

  • Input iterators require special care. Rewrite your loop this way and the behavior will become similar to any other character input loop:

    while (it != eos)
    {
        clog << *it;
        it++;
    }
    

    That will take care of "Why it doesn't print the last character"

    PS: as for EOF in the middle of the line, it is the POSIX-mandated behavior:

    When received, all the bytes waiting to be read are immediately passed to the process without waiting for a newline, 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.