如果用户输入某些内容,则在语句之间切换:无限且超时[重复]

问题描述 投票:0回答:1

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

如果用户输入了一些内容,一个简单的

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

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

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

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#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;
}

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

另一方面,如果我在无限循环中声明

fd_set
struct timeval
inside,一旦我输入某些内容,就会无限地打印出已按下某个键 ,就好像 它会忽略超时。

我不知道为什么这么简单的代码不起作用。我想我遗漏了一些我不知道的文件描述符的要点。

c file-descriptor posix-select timeval
1个回答
1
投票

因为你应该重置 ->

FD_ZERO(&readfds)
你的
readfds
并添加文件描述符 ->
FD_SET(STDIN, &readfds)
每次
select
返回时,因为超时时文件描述符将从集合中删除

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#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
看看发生了什么,然后检查您感兴趣的文件描述符in 包含在
readfds
中。

© www.soinside.com 2019 - 2024. All rights reserved.