我正在尝试使用select()来读取键盘输入,我陷入困境,因为我不知道如何从键盘读取并使用文件描述符来执行此操作。我被告知使用STDIN和STDIN_FILENO来解决这个问题,但我仍然感到困惑。
我该怎么办?
答案 0 :(得分:5)
你的问题听起来有点困惑。 select()
用于阻止输入可用。但是你使用普通的文件阅读功能(例如read
,fread
,fgetc
等)进行实际阅读。
这是一个简单的例子。它会阻塞,直到stdin至少有一个字符可供阅读。但是当然除非你将终端更改为某种未烹饪模式,否则它会一直阻塞,直到你按下回车键,当任何输入的字符被刷新到文件缓冲区中时(从某个终端缓冲区)。
#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;
}
答案 1 :(得分:4)
正如已经说过的那样,使用select,您只需监控,例如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] = '\0';
printf("'%s' was read from stdin.\n", buff);
}
else
printf("No data within five seconds.\n");
exit(EXIT_SUCCESS);
}
答案 2 :(得分:1)
也许,你想要在“WINDOWS”上偷看键盘输入的方式? 在Windows上,它无法从STDIN的select()获得结果。您应该使用PeekConsoleInput()。 并使用stdin的句柄如下。
hStdin = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE, ...
stdin可能成为管道输入。如果是这样,你就不会输入任何键盘。
P.S。如果你不问Windows,很抱歉。