如何确定STDIN是否为空?

时间:2011-05-04 09:18:48

标签: c++ iostream

我正在为我的操作系统课程编写模拟器。我遇到的问题是我们需要从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时终止。

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

4 个答案:

答案 0 :(得分:4)

我认为没有一种独立于平台的方法,但是在基于Unix的系统上你应该能够做到:

#include <unistd.h>
...

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

    ...
}

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

答案 1 :(得分:2)

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

./RMMIX < aJob.job
你说:

./RMMIX aJob.job

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

答案 2 :(得分:2)

你也可以看看这个http://www.programmersheaven.com/mb/CandCPP/232821/232821/non-blocking-reads-on-stdin/从另一个方向出现问题的想法 - 不要检查流上的字节数,而只是让读取立即成功,然后检查看是否有任何内容被阅读。

答案 3 :(得分:0)

您可以在命令行上按Ctrl + D,以指示正在运行的程序上标准输入的文件结尾。

这是理想的行为。否则,如果程序在没有输入的情况下立即退出,则管道可能会被等待另一个尚未安排运行的命令(并且没有产生任何额外输出)的命令随机打破,或者缓冲输出并将其全部发出马上就像sort一样。

当使用io重定向通过类似./RMMIX < file.txt之类的文件从文件中提取标准输入时,如果文件中没有剩余数据,则会自动发出此文件结束条件。对于从终端读取的输入,等待可能是期望的行为。