测试stdin是否有C++输入(windows和/或linux)

nor*_*lli 13 c++ testing stdin pipe

我基本上想测试stdin是否有输入(如果你回显并管道它).我找到了有效的解决方案,但它们很难看,而且我喜欢我的解决方案.

在linux上我用这个:

bool StdinOpen() {
  FILE* handle = popen("test -p /dev/stdin", "r");
  return pclose(handle) == 0;
}
Run Code Online (Sandbox Code Playgroud)

我知道我应该添加更多的错误处理,但除此之外.

在Windows上我用这个:

bool StdinOpen() {
  static HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
  DWORD bytes_left;
  PeekNamedPipe(handle, NULL, 0, NULL, &bytes_left, NULL);
  return bytes_left;
}
Run Code Online (Sandbox Code Playgroud)

对于linux来说这很好,但我想知道在不使用管道的情况下我可以调用的等效API(就像test -f $file你一样fopen($file, "r") != NULL).我有能力open("/dev/stdin", "r")和做同样的事情,但我想知道最好的方法.

简介:我想知道可以用来代替test -p /dev/stdinlinux 的API ,如果你知道一个更好的Windows解决方案.

Ant*_*tti 14

这是POSIX(Linux)的解决方案:我不确定在Windows上什么是poll().在Unix上,编号为0的文件描述符是标准输入.

#include <stdio.h>
#include <sys/poll.h>

int main(void)
{
        struct pollfd fds;
        int ret;
        fds.fd = 0; /* this is STDIN */
        fds.events = POLLIN;
        ret = poll(&fds, 1, 0);
        if(ret == 1)
                printf("Yep\n");
        else if(ret == 0)
                printf("No\n");
        else
                printf("Error\n");
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

测试:

$ ./stdin
No
$ echo "foo" | ./stdin
Yep
Run Code Online (Sandbox Code Playgroud)

  • +1.另一种常用的替代方法是`select()` - 概念上类似的用法.重要的是要注意这些问操作系统是否有来自描述符的新数据 - 如果你在那个级别操作,你必须直接在描述符上使用`read()`,你不能使用库 - level stdin streams或`std :: cin`(除非你提供一个新的缓冲区实现). (2认同)

Mat*_*ins 5

这行不通吗?

std::cin.rdbuf()->in_avail();
Run Code Online (Sandbox Code Playgroud)