Проверьте, имеет ли 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.
Ответы
Ответ 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();