测试STDIN是否有C++(Windows和/或Linux)输入

测试STDIN是否有C++(Windows和/或Linux)输入,c++,testing,pipe,stdin,C++,Testing,Pipe,Stdin,我基本上想测试stdin是否有输入,比如你是否回显和管道。我已经找到了有效的解决方案,但它们是丑陋的,我喜欢我的解决方案是干净的 在linux上,我使用以下命令: bool StdinOpen() { FILE* handle = popen("test -p /dev/stdin", "r"); return pclose(handle) == 0; } bool StdinOpen() { static HANDLE handle = GetStdHandle(STD_INPU

我基本上想测试stdin是否有输入,比如你是否回显和管道。我已经找到了有效的解决方案,但它们是丑陋的,我喜欢我的解决方案是干净的

在linux上,我使用以下命令:

bool StdinOpen() {
  FILE* handle = popen("test -p /dev/stdin", "r");
  return pclose(handle) == 0;
}
bool StdinOpen() {
  static HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
  DWORD bytes_left;
  PeekNamedPipe(handle, NULL, 0, NULL, &bytes_left, NULL);
  return bytes_left;
}
我知道我应该添加更多的错误处理,但这不是重点

在windows上,我使用以下命令:

bool StdinOpen() {
  FILE* handle = popen("test -p /dev/stdin", "r");
  return pclose(handle) == 0;
}
bool StdinOpen() {
  static HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
  DWORD bytes_left;
  PeekNamedPipe(handle, NULL, 0, NULL, &bytes_left, NULL);
  return bytes_left;
}
这对于linux来说很好,但我想知道,在不使用类似管道的test-f$file的情况下,我可以调用哪些等效API?fopen$file,r!=无效的我知道我可以打开/dev/stdin,r并做同样的事情,但我想知道最好的方法


小结:我想知道我可以用哪些API来代替linux的test-p/dev/stdin,如果你知道一个更好的windows解决方案的话。

我不确定,但它能满足你的需要吗?

这里有一个POSIX linux解决方案:我不确定在windows上轮询的等价物是什么。在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;
}
这样不行吗

std::cin.rdbuf()->in_avail();

如果标准输入是文件句柄而不是管道,则PeekNamedPipe解决方案将失败。此外,句柄变量不应该是静态的。如果你的应用程序运行时句柄被重定向,你以后会给自己一个惊喜。@Billy:我认为句柄不会被随机重定向。当然,你可能会改变你认为是STDIN,但旧的手柄仍然存在。但是我同意第一部分。Lionel B在提供了一些Linux代码-讨论也值得一读。我可以测试stdin是否是使用DWORD dw;的管道!GetConsoleModehandle、&dw并使用当前方法,否则使用_kbhit!=0想法?这正是我想要的。现在,如果你能告诉我如何测量输入缓冲区的大小,我将万分感激,但我不想听起来像个爱提问的人。你可以使用read来获取输入。首先使用fcntl将文件描述符0设置为非阻塞,然后read将返回读取的字节数,或者在没有更多传入数据时返回0。+1。另一个常用的替代方法是选择-概念上类似的用法。需要注意的是,这些命令会询问操作系统描述符是否有新的可用数据-如果您在该级别上操作,那么您也必须直接在描述符上使用read命令,除非提供新的缓冲区实现,否则不能使用库级stdin streams或std::cin。在我的平台上,我可以使用fds.fd=filenostin而不是fds.fd=0。如果需要的话,这将提高平台独立性,即使不确定是否有一个stdin的fd为非零的平台。我使用的是一个3.2内核的ARM Linux发行版。是的,它至少更具可读性。POSIX将stdin fileno定义为0—请参阅stdin3p—还有一个在stdio.h中定义了值为0的define stdin_fileno。这对我来说很有效,也很简单。