如何知道用户在C语言中一分钟后是否输入了某些内容

时间:2016-12-24 23:18:33

标签: c scanf

我正在进行的项目 - 扫雷游戏 - 要求当用户闲置并且不会输入一分钟的时间时,需要更新时间。这正是教授如何说的#34;当用户闲置一分钟时,更新时间。" 所以我怎么知道scanf没有返回任何东西一分钟,所以我可以采取某种行动。因为根据我的理解,scanf函数必须扫描一些内容才能继续下一行。

2 个答案:

答案 0 :(得分:1)

此处还有2个选项: -

  1. Poll()函数(可能是Linux上最“正确”的方式)
  2. #include <poll.h>
    #include <stdio.h>
    #include <unistd.h>    
    int main()
    {
        struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
        char string[10];
    
        if( poll(&mypoll, 1, 10000) )
        {
            scanf("%9s", string);
            printf("Read string - %s\n", string);
        }
        else
        {
            puts("Read nothing");
        }
    
        return 0;
    }
    

    超时是轮询的第三个参数,以毫秒为单位 - 此示例将在stdin上等待10秒。 Windows有WSAPoll,它的工作方式应该类似。

    1. 尝试闹钟()
    2. 这是解决问题的另一种方法。

      #include <stdio.h>
      #include <unistd.h>
      int main(void)
      {
           char buf [10];
           alarm(10);
           scanf("%s", buf);
           return 0;          
      }
      

答案 1 :(得分:0)

cannonical模式下的终端是行缓冲的。您需要将终端切换到原始模式,以便您的应用可以在他们输入时看到按键,然后您可以使用同步读取功能,如read / scanf和基于信号的定时器或像select这样的函数。

E.g。 (基于https://linux.die.net/man/2/select的例子):

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

int main(void)
{
    fd_set rfds;
    struct timeval tv;
    int retval;

    struct termios oldt, newt;


    //switch terminal to raw mode
    tcgetattr( STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    /* Watch stdin (fd 0) to see when it has input. */
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);

    /* Wait up to two seconds. */
    tv.tv_sec = 2;
    tv.tv_usec = 0;

    retval = select(1, &rfds, NULL, NULL, &tv);
    /* Don't rely on the value of tv now! */

    if (retval == -1)
        perror("select()");
    else if (retval)
        printf("Data is available now.\n");
    /* FD_ISSET(0, &rfds) will be true. */
    else
        printf("No data within two seconds.\n");

    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
    return 0;
}