istream_iterator在读取字符时忽略EOF(Ctrl + D)

时间:2011-09-07 17:33:30

标签: c++ eof cin istream istream-iterator

我正在尝试使用istream_iterator来阅读cin中的字符。我已经读过按 Ctrl + D 发送一个结束输入流的EOF字符。不幸的是,它出了问题。这是我的代码:

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

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

我正在运行它并键入:as df,然后按 Ctrl + D 。 它仅输出asd而没有最后f,然后挂起等待输入。当我键入gh并再次按 Ctrl + D 时,它会打印最后剩余的f,然后打印下一个g输入,但没有最后h。当我最后按 Ctrl + D 而不输入任何内容时,它会打印剩余的h并退出。

我希望它能阅读asdf并退出,因为我已经在第一个序列的末尾按了 Ctrl + D

为什么在获得EOF后仍在等待输入? 为什么不打印EOF之前读取的最后一个字符? 为什么只有当我按 Ctrl + D 而不先输入任何内容时才会退出?
这个循环如何改变以使其按照我期望的方式运行? (即在输入中获得 Ctrl + D 序列后立即停止读取,无论我之前输入的是否有任何内容,并且读取所有字符到EOF)。

2 个答案:

答案 0 :(得分:6)

输入迭代器需要特别小心。以这种方式重写循环,行为将变得类似于任何其他字符输入循环:

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

这将照顾“为什么它不打印最后一个字符”

PS:对于行中间的EOF,它是POSIX-mandated behavior

  

当收到时,等待读取的所有字节立即传递给进程而不等待换行,并且EOF被丢弃。因此,如果没有字节等待(即,EOF发生在一行的开头),则应从read()返回一个零字节计数,表示文件结束指示。

答案 1 :(得分:3)

在类Unix系统上,键入 Ctrl + D 仅在行的开头触发文件结束条件(即,在键入输入。要在行中间触发文件结束条件,请键入 Ctrl + D 两次。