【问题标题】:istream_iterator ignoring EOF (Ctrl+D) when reading charsistream_iterator 在读取字符时忽略 EOF (Ctrl+D)
【发布时间】:2023-04-05 12:36:02
【问题描述】:

我正在尝试使用 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 序列后立即停止阅读,无论我之前是否输入过任何内容,并阅读 all 个字符到EOF)。

【问题讨论】:

  • 如果您使用的是 Windows/DOS,EOF 是 CTRL+Z,而不是 CTRL+D
  • 我知道。但感谢您完成。

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


【解决方案1】:

输入迭代器需要特别注意。以这种方式重写您的循环,其行为将与任何其他字符输入循环相似:

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

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

PS:至于中间的EOF,就是POSIX-mandated behavior

收到后,所有等待读取的字节立即传递给进程,无需等待换行符,EOF 被丢弃。因此,如果没有等待的字节(即 EOF 发生在行首),则 read() 将返回零字节计数,表示文件结束指示。

【讨论】:

  • 非常感谢! :) 现在它可以按我的预期工作:) (考虑到 Keith Thompson 在下面写的内容以及您在更新答案中的内容)。但是你能解释一下什么是“特殊护理”以及为什么需要它吗? (即为什么你的代码有效而我的无效)。我想更好地理解它,而不仅仅是复制粘贴。
  • *(it++) 强制输入迭代器在输出之前已读取的内容之前从输入流中进行读取。因此,在收到第一个 CTRL+D 后,您的最后一个字符已经被读取,但在您输入另一个字符之前无法输出(在这种情况下,另一个 CTRL+D 表示 EOF)。排序*itit++ 现在会在尝试读取另一个字符之前输出先前读取的字符。因此,您的最后一个字符被打印出来,然后输入等待最后一个 CTRL+D 来指示一行中间的 EOF。
  • @SasQ 我被击败了 14 秒,但要添加一些细节,输入迭代器在递增时读取,即 read() 是评估 it++ 的副作用,并且在对operator&lt;&lt;() 的函数调用,其参数(clog*it++)的副作用必须是完整的。这就是它如何强制读取发生在输出之前,即使意图(根据后增量判断)是相反的。
  • @Jason:感谢您的解释。现在我明白了。
  • @Cubbi:别担心;)你的努力也得到了回报。
【解决方案2】:

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

【讨论】:

  • 啊,这回答了我的一个问题:为什么Ctrl+D 不会在我之前输入一些内容时结束流。这让我很清楚。但是我仍然想知道为什么在输入某些内容后推Ctrl+D确实 将这些字符发送到我的程序并出现。就像Ctrl+D 有点工作(它会停止读取输入一段时间),但不是EOF 的全部功能(完全关闭流)。
    顺便说一句,你如何制作那些漂亮的按钮状文本周围的框架? :>
  • 好吧,没关系,我用这些按钮状的边框弄明白了 ;)
  • @SasQ:看起来 Ctrl+D 中断了行缓冲,所以程序可以立即看到输入的内容,即使它不在行尾。我不是 100% 确定这一点。我确定它记录在某处。哦,它是“Ctrl+D”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 2020-10-01
  • 1970-01-01
相关资源
最近更新 更多