gpt4 book ai didi

c - 如何在退出程序前开始计时 5 秒?

转载 作者:太空宇宙 更新时间:2023-11-04 01:46:56 25 4
gpt4 key购买 nike

我已经为此苦恼好几个小时了。基本上,我有一个程序要求用户输入他的密码 (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;
}

最佳答案

您的主要挑战是 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;
}

注意事项:

  • select() 的最后一个参数是一个 struct timeval,它指定等待指定文件描述符上的事件的时间。在这种情况下,我指定了 50 毫秒的超时。
  • 终端需要置于字符缓冲区模式而不是行缓冲模式。 (否则每次出现新字符时都需要按回车键。)

操作系统支持

select() 是 POSIX 规范的一部分,但我不知道它是否在 Windows 上实现。也许有人可以澄清一下?

另外...我也不知道设置终端属性是否会在 Windows 上按预期工作。 (我只在 Linux 上测试过。)

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

关于c - 如何在退出程序前开始计时 5 秒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51957319/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com