如果用户输入内容,则在语句之间切换:无限且超时

为了更清楚地解释我想要做什么,我希望我的代码检查用户是否输入了一些东西(或者如果另一个文件描述符超过0有数据要读取)每个(比方说)2.5秒,直到程序停止。

如果用户输入内容,则简单的printf()将通知他,然后程序将再次检查用户是否在接下来的2.5秒内输入了内容。

否则,它应该只是打印时间用完,然后在接下来的2.5秒内再次检查用户输入。

这是我从Beej的网络编程指南中窃取的代码片段,并修改为(尝试)满足我的要求:

 #include  #include  #include  #include  #define STDIN 0 // file descriptor for standard input int main(void){ struct timeval tv; fd_set readfds; FD_ZERO(&readfds); FD_SET(STDIN, &readfds); tv.tv_sec = 2; tv.tv_usec = 500000; while(1){ select(STDIN+1, &readfds, NULL, NULL, &tv); if (FD_ISSET(STDIN, &readfds)){ printf("A key was pressed!\n"); tv.tv_sec = 2; tv.tv_usec = 500000; }else{ printf("Timed out.\n"); tv.tv_sec = 2; tv.tv_usec = 500000; } } return 0; } 

只要我不按任何键,这个工作正常并打印“Timed out”。 每2.5秒。 但如果我输入某些内容,它似乎会忽略用户输入并继续打印“超时”。

另一方面,如果我在无限循环中声明fd_setstruct timeval ,一旦我输入了某些内容,就会无限打印出一个按键,就好像它忽略了超时一样。

我不知道为什么这么简单的代码不起作用。 我想我错过了一些关于我不知道的文件描述符的观点。

因为你应该重置 – > FD_ZERO(&readfds)你的readfds并在每次select返回时添加文件desciptor – > FD_SET(STDIN, &readfds) ,因为在超时时文件描述符从集合中删除

 #include  #include  #include  #include  #define STDIN 0 // file descriptor for standard input int main(void){ struct timeval tv; fd_set readfds; while (1) { int count; /* how many descriptors are contained in the set. */ FD_ZERO(&readfds); FD_SET(STDIN, &readfds); tv.tv_sec = 2; tv.tv_usec = 500000; count = select(STDIN + 1, &readfds, NULL, NULL, &tv); if ((count > 0) && (FD_ISSET(STDIN, &readfds) != 0)) { printf("A key was pressed!\n"); } else if (count == -1) /* check for the error here */ } else { printf("Timed out.\n"); } } return 0; } 

如你所见,你也应该检查select的返回值,检查错误,如果有错误,然后检查errno以查看发生了什么,然后检查你感兴趣的文件descritor是否包含在readfds