Как использовать Select() для чтения ввода с клавиатуры в C
Я пытаюсь использовать Select() для чтения ввода с клавиатуры и я застрял в том, что я не знаю, как читать с клавиатуры и использовать дескриптор файла для этого. Мне сказали использовать STDIN и STDIN_FILENO для решения этой проблемы, но я все еще смущен.
Как я могу это сделать?
3 ответов
Ваш вопрос звучит немного смущенно. select()
используется для блокировки, пока не будет доступен вход. Но вы делаете фактическое чтение с обычными функциями чтения файлов (например,read
,fread
,fgetc
, etc.).
вот краткий пример. Он блокирует, пока stdin не будет иметь хотя бы один символ, доступный для чтения. Но, конечно, если вы не измените терминал на какой-то необработанный режим, он блокируется до тех пор, пока вы не нажмете enter, когда любые введенные символы будут сброшены в буфер файлов (из некоторых терминальный буфер).
#include <stdio.h>
#include <sys/select.h>
int main(void) {
fd_set s_rd, s_wr, s_ex;
FD_ZERO(&s_rd);
FD_ZERO(&s_wr);
FD_ZERO(&s_ex);
FD_SET(fileno(stdin), &s_rd);
select(fileno(stdin)+1, &s_rd, &s_wr, &s_ex, NULL);
return 0;
}
Как уже было сказано, с помощью выберите вы можете просто контролировать, например, stdin, чтобы проверить, доступны ли входные данные для чтения или нет. Если он доступен, вы можете использовать, например,fgets безопасно считывать входные данные в какой-то буфер, как показано ниже:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
fd_set rfds;
struct timeval tv;
int retval, len;
char buff[255] = {0};
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval == -1){
perror("select()");
exit(EXIT_FAILURE);
}
else if (retval){
/* FD_ISSET(0, &rfds) is true so input is available now. */
/* Read data from stdin using fgets. */
fgets(buff, sizeof(buff), stdin);
/* Remove trailing newline character from the input buffer if needed. */
len = strlen(buff) - 1;
if (buff[len] == '\n')
buff[len] = '';
printf("'%s' was read from stdin.\n", buff);
}
else
printf("No data within five seconds.\n");
exit(EXIT_SUCCESS);
}
возможно, вы хотите, чтобы способ заглянуть ввода клавиатуры на "WINDOWS"? В windows он не может получить результат от select() для STDIN. Вы должны использовать PeekConsoleInput(). И используйте ручку stdin, как следующее.
hStdin = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE, ...
stdin может стать входом трубы. если это так, вы не получаете ввода с клавиатуры.
P. S. Если вы не просите о Windows, очень жаль.