如果用户输入某些内容,则在语句之间切换:无限且超时 [英] Switching between statements if the user inputs something: infinitely and with a timeout

查看:92
本文介绍了如果用户输入某些内容,则在语句之间切换:无限且超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了更清楚地说明我要做什么,我希望我的代码每隔2.5秒(例如)检查一次用户是否输入了某些内容(或者说另一个文件描述符(非0的文件描述符中有要读取的数据)),以此类推,直到程序停止

To explain more clearly what I want to do, I want my code to check if the user inputs something (or if another file descriptor than 0 has data to read) every (let's say) 2.5 seconds and so until the program stops.

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

If the user inputs something, a simple printf() will notify him and then the program will check again if the user inputs something in the next 2,5 seconds.

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

Else, it should simply print that the time ran out and then check again for the user input in the next 2,5 seconds.

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

And here's the code snippet I stole from Beej's Guide to Network Programming and modified to (try to) fulfill my requirements:

#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秒.但是,如果我输入了某些内容,它会似乎忽略用户输入,并继续打印超时".

As long I don't press any key, this works fine and prints "Timed out." every 2,5 seconds. But if I enter something, it seems to ignore the user input and keeps printing "Timed out.".

另一方面,如果我在无限循环中声明fd_setstruct timeval ,一旦输入内容,它将无限打印出已按下的键如果,它将忽略超时.

On the other hand, if I declare the fd_set and the struct timeval inside the infinite loop, once I enter something, this prints infinitely that a key has been pressed as if it ignores the timeout.

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

I have no idea why such a simple code doesn't work. I guess I'm missing some point about file descriptors I don't know about.

推荐答案

因为您应该重置-> FD_ZERO(&readfds)您的readfds,并且每次select返回时都添加文件描述符-> FD_SET(STDIN, &readfds),因为自超时以来文件描述符已从集合中删除

Because you should reset -> FD_ZERO(&readfds) your readfds and add the file desciptor -> FD_SET(STDIN, &readfds) every time select returns, since on timeout the file descriptor is removed from the set

#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以查看发生了什么,然后将其检查为文件描述符.感兴趣的内容包含在readfds中.

as you see you should also check the return value from select, to check for an error, in case of an error, then check errno to see what happened, and then you check it the file descritor you're interested in is contained in readfds.

这篇关于如果用户输入某些内容,则在语句之间切换:无限且超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆