Подтвердить что ты не робот

Проверьте, имеет ли stdin вход для С++ (windows и/или linux)

В основном я хочу проверить, имеет ли вход 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;
}

Это нормально для linux, но я хочу знать, какие эквивалентные API, которые я могу назвать, не используя канал (например, для test -f $file вы делаете fopen($file, "r") != NULL). У меня есть подозрение, что я мог бы open("/dev/stdin", "r") и делать то же самое, но я хочу знать, как это сделать.

Резюме: Я хочу знать API, которые я мог бы использовать для замены test -p /dev/stdin для linux, и, если вы знаете лучшее решение для Windows.

4b9b3361

Ответ 1

Здесь решение для POSIX (Linux): Я не уверен, что эквивалент poll() в 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;
}

Тестирование:

$ ./stdin
No
$ echo "foo" | ./stdin
Yep

Ответ 2

Я не уверен, но _kbhit() делает то, что вам нужно?

Ответ 3

Неужели это не сработает?

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