我正在尝试使用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
)。
答案 0 :(得分:6)
输入迭代器需要特别小心。以这种方式重写循环,行为将变得类似于任何其他字符输入循环:
while (it != eos)
{
clog << *it;
it++;
}
这将照顾“为什么它不打印最后一个字符”
PS:对于行中间的EOF,它是POSIX-mandated behavior:
当收到时,等待读取的所有字节立即传递给进程而不等待换行,并且EOF被丢弃。因此,如果没有字节等待(即,EOF发生在一行的开头),则应从read()返回一个零字节计数,表示文件结束指示。
答案 1 :(得分:3)
在类Unix系统上,键入 Ctrl + D 仅在行的开头触发文件结束条件(即,在键入输入。要在行中间触发文件结束条件,请键入 Ctrl + D 两次。