C 退出程序前如何开始计数5秒?

C 退出程序前如何开始计数5秒?,c,C,我已经为此烦恼了好几个小时了。基本上,我有一个程序,要求用户输入密码(123),如果用户在5秒钟内没有输入任何内容,那么程序将退出(游戏结束)。我一直在尝试使用time(NULL)和clock(),但仍然没有成功。有人能给我指一下正确的方向吗?提前多谢 这是我的密码: #include <stdio.h> #include <time.h> int main(){ int password = 0; int num = 0; printf("%s\n

我已经为此烦恼了好几个小时了。基本上,我有一个程序,要求用户输入密码(123),如果用户在5秒钟内没有输入任何内容,那么程序将退出(游戏结束)。我一直在尝试使用time(NULL)和clock(),但仍然没有成功。有人能给我指一下正确的方向吗?提前多谢

这是我的密码:

#include <stdio.h>
#include <time.h>

 int main(){
   int password = 0;
   int num = 0;
   printf("%s\n", "Please enter your password");
   scanf("%d", &password);
   // Here I need to check if user didnt enter anything for 5 seconds,
   // and if he didnt enter anything then exit out of the program
   // I tried using time
   // time_t start = time(NULL);
   // time_t stop = time(NULL);
   //   if(((stop - start) * 1000) > 5000){
   //  printf("%s\n", "Game Over");
   //  break;          
  //  }

   printf("%s\n", "Thank you for entering your password, now enter any number");
   scanf("%d", &num);
   return 0;
 }
#包括
#包括
int main(){
int密码=0;
int num=0;
printf(“%s\n”,“请输入您的密码”);
scanf(“%d”和密码);
//这里我需要检查用户是否在5秒钟内没有输入任何内容,
//如果他没有输入任何内容,那么退出程序
//我试着利用时间
//时间\u t开始=时间(空);
//时间\u t停止=时间(空);
//如果(((停止-启动)*1000)>5000){
//printf(“%s\n”,“游戏结束”);
//中断;
//  }
printf(“%s\n”,“谢谢您输入密码,现在输入任意数字”);
scanf(“%d”和&num);
返回0;
}

您的主要挑战是
scanf()
-以及
getchar()
和类似的命令-正在阻塞。在用户实际输入任何输入之前,可能会经过一段未知的时间间隔,而您的五秒钟可能已经到了该阶段

select()
-监控文件描述符超时 我认为最可行的选择之一是使用
select()
——它监视某些文件描述符集上的活动。具体来说,您需要监视
stdin
文件描述符上的活动

我相信,以下几点可以达到您所需要的效果

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

int main(void) {
    char buf[16] = {'\0'};
    char *pass = buf;
    time_t time_update = 0, time_now = 0;
    struct timeval tm;
    int res = 0;
    struct termios term_attr, new_attr;
    fd_set rset;

    // Change terminal attributes (We don't want line-buffered mode.)
    tcgetattr(fileno(stdin), &term_attr);
    tcgetattr(fileno(stdin), &new_attr);
    new_attr.c_lflag &= ~(ICANON | ECHO);

    tcsetattr(fileno(stdin), TCSANOW, &new_attr);

    printf("Enter password: ");

    time_update = time(NULL);
    while (1) {
        tm.tv_sec = 0;
        tm.tv_usec = 50000;
        FD_ZERO(&rset);
        FD_SET(STDIN_FILENO, &rset);

        res = select(fileno(stdin) + 1, &rset, NULL, NULL, &tm);
        if (FD_ISSET(STDIN_FILENO, &rset)) {
            time_update = time(NULL);
            int c = getchar();
            if (c == '\n') {
                break;
            }
            *pass = c;
            pass++;
        }
        time_now = time(NULL);
        if (time_now - time_update >= 5) {
            puts("Timed out ...");
            break;
        }
    }

    pass = buf;

    printf("You entered: %s \n", pass);

    // Restore original terminal attributes
    tcsetattr(fileno(stdin), TCSANOW, &term_attr);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
内部主(空){
char buf[16]={'\0'};
char*pass=buf;
time\u t time\u update=0,time\u now=0;
struct-timeval-tm;
int res=0;
结构术语属性,新属性;
fd_集rset;
//更改终端属性(我们不需要行缓冲模式。)
tcgetattr(文件号(标准输入)和术语属性);
tcgetattr(文件号(标准输入)和新属性);
新的_attr.c_lflag&=~(ICANON | ECHO);
tcsetattr(文件号(标准输入)、TCSANOW和新属性);
printf(“输入密码:”);
时间\更新=时间(空);
而(1){
tm.tv_sec=0;
tm.tv_usec=50000;
FD_零和rset;
FD_集(标准文件号和rset);
res=select(fileno(stdin)+1,&rset,NULL,NULL,&tm);
if(FD_ISSET(标准文件号和rset)){
时间\更新=时间(空);
int c=getchar();
如果(c=='\n'){
打破
}
*通过=c;
pass++;
}
time_now=时间(空);
如果(现在时间-更新时间>=5){
放置(“超时…”);
打破
}
}
通过=buf;
printf(“您输入了:%s\n”,通过);
//恢复原始终端属性
tcsetattr(文件号(stdin)、TCSANOW和term_attr);
返回0;
}
注释

  • select()
    的最后一个参数是
    struct timeval
    ,它指定在指定的文件描述符上等待活动的时间。在本例中,我指定了50毫秒的超时
  • 终端需要置于字符缓冲模式,而不是行缓冲模式。(否则,每次出现新字符时都需要按enter键。)
操作系统支持
select()
是POSIX规范的一部分,但我不知道它是否在Windows上实现。也许有人能澄清一下

还有。。。我不知道在Windows上设置终端属性是否也能像预期的那样工作。(我只在Linux上测试过。)


我意识到这个解决方案可能比您希望的要长/复杂一些,但我不知道有什么更简单的方法。

我的2分钱是这个任务需要进程或线程不要使用
break
use
return 0
对于初学者来说,
scanf
也是一个阻塞调用,您需要使用
fork
或类似的工具来完成您的任务want@snr如何实现线程?@Mitchel0022在使用return 0后,如果用户没有输入任何内容,如何让它工作并在5秒后退出程序?启动一个休眠5秒的pthread,然后检查一个原子“用户输入”是相当简单的如果未设置,则终止进程。这样做比乱用select()更容易。