【问题标题】:How to Determine if STDIN is Empty?如何确定 STDIN 是否为空?
【发布时间】:2011-05-04 09:18:48
【问题描述】:

我正在为我的操作系统课程编写一个模拟器。我遇到的问题是我们需要从 STDIN 获取所有的 .job 文件(它们就像被馈送到模拟器的应用程序)并将它们读入。

呼叫:

./RMMIX < aJob.job

我只是啜饮它

while(getline(std::cin, line)) 

一行一行。问题是,如果我不向 STDIN 输入任何内容,那么 cin 将等待用户输入——而不是我想要的。我需要程序识别 STDIN 上缺少文本并终止,而不是等待用户输入。

我已经确定我可以像这样查询长度:

size_t beg = std::cin.tellg();
std::cin.seekg(0, std::ios_base::end);
size_t end = std::cin.tellg();
std::cin.seekg(0, std::ios_base::beg);

如果 std::cin 的长度为 0 则终止。

还有其他解决方案吗?这是便携式解决方案吗?

【问题讨论】:

  • 如果不使用某些系统特定的代码,我认为您无法做到。如果 cin 连接到控制台,EOF 条件是我将按下 Ctrl+D/Ctrl+Z 作为我的下一个输入。系统只需要等到我输入内容才能做出决定!
  • 流没有长度。它们是信息流,而不是容器。实际上,您是在询问cin 的读取缓冲区的填充部分的长度。
  • 你的代码试图做的是有效地在管道中寻找,据我所知是未定义的。
  • 如果您不使用 &lt; 重定向任何内容,那么标准输入中会有 的内容。用户输入。你必须&lt; /dev/null。那么就什么都没有了,因为/dev/null 总是空的。
  • 希望它等待用户输入。这就是现在所有期望标准输入数据的程序的行为,所以如果你的不同,你只会混淆要运行它的人。

标签: c++ iostream


【解决方案1】:

我不认为有独立于平台的方式来做到这一点,但在基于 Unix 的系统上你应该能够做到:

#include <unistd.h>
...

int main() {
    if (!isatty(0)) {
        // stdin is being streamed from a file or something else that's not a TTY.
    }

    ...
}

但是,我认为通过命令行选项执行此操作是首选方法。

【讨论】:

  • 这应该是isatty(STDIN_FILENO)isatty(fileno(stdin)),如果是后者,则使用-D_POSIX_SOURCE 编译。
【解决方案2】:

您需要重新设计您的程序。不是从标准输入读取,而是从命名文件中读取,您在命令行上提供的名称。然后代替:

./RMMIX < aJob.job

你说:

./RMMIX aJob.job

这比尝试确定标准输入中是否有任何内容更容易且更便携。

【讨论】:

  • @unpersson:这是我喜欢的做事方式(对 boost::program_options 表示赞赏),但你知道教授……必须按照他们想要的方式做事,而不是什么更好。
  • @SoulBeaver 我确实认识教授——我曾经是其中的一员,我们中的许多人都是相当通情达理的人。要么向他解释他想要的东西无法完成,要么让他解释如何去做——毕竟这是他的工作!
  • 我不同意这个答案。我不知道 OP 的程序做了什么,但这与 unix-philosophy 非常相似,并且鼓励低效的使用,例如创建临时文件(如果需要在管道中运行)(否则会使在脚本)。操作:您的讲师很可能知道并期望您的程序在没有重定向到标准输入的情况下被调用时会等待输入。我知道这是一个老问题,但我觉得有必要说一下。
【解决方案3】:

您还可以查看http://www.programmersheaven.com/mb/CandCPP/232821/232821/non-blocking-reads-on-stdin/ 以了解从另一个方向来解决问题的想法——不要检查流上的字节数,而是立即使读取成功,然后检查以查看如果有什么被读过。

【讨论】:

    【解决方案4】:

    您可以在命令行上按 Ctrl+D 以在正在运行的程序上发出标准输入的文件结束信号。

    这是期望的行为。否则,如果程序在没有输入时立即退出,管道可能会被正在等待另一个尚未计划运行的命令(并且没有产生任何额外输出)的命令随机中断,或者缓冲输出并全部发出一次,就像sort 一样。

    当使用 io 重定向通过 ./RMMIX &lt; file.txt 之类的方式从文件中提取标准输入时,当文件中没有更多数据时,会自动发出此文件结束条件的信号。对于从终端读取的输入,等待可能是期望的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 2011-07-12
      • 2020-08-31
      • 1970-01-01
      • 2015-09-28
      相关资源
      最近更新 更多