如何在 C 程序开始时开始计时

How to start counting time at the start of my program in C

我正在制作一款游戏,您必须破解这样的系统:键入您在屏幕上看到的数字:12345 在 10 秒内。我想知道如何在 10 秒过去时警告玩家,比如在屏幕上打印 "Too slow!!!!!!"。我尝试了 sleep() 函数,但它停止了程序,而 sleep() 函数是 运行!

规则: 当您启动程序时,屏幕上会出现:

Enter code:           Hack 1.

如果您键入 1 并输入一个随机数,您必须覆盖它。如果失败出现:

Hacking failed!!!!!!!!.

如果你太慢,它会出现:

Too slow!!!!!!!

但是那件事 "Too slow!!!!!!" 只发生在程序结束时!

这是我的代码:

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

int main ()
{
    time_t start, end;
    double need;
    int i;
    double number;
    int t = 15;
z:
    printf("Enter the code:                    Hack 1  :");
    scanf("%d", &i);
    if(i == 123456789)
    {
        printf("Enter the room.");
    }
    if(i == 1)
    {
        printf("You've got %d seconds. Press 1 to start hacking the system:", t);
        scanf("%d", &i);
        if(i == 1)
        {
            //Appears a random number and time starts counting
            time (&start);
            srand(time(NULL));
            double rn = (rand() % 1000000000000000000);
            printf("%f type here: ", rn);
            scanf("%lf", &number);
            if(number == rn)
            {
                //Time ends
                time (&end);
                //Calculate elapsed time
                need = difftime (end, start);
                //If you're too late
                if(need > t)
                {
                    printf("Too late!!!!!!!!!!!");
                }
                else
                {
                    //If you success
                    printf("System hacked. Enter the room. ");
                    t--;
                    goto z;
                }
            }
            else
            {
                //If you fail
                printf("Hacking failed!!!!!!!!!!");
            }
        }
    }
}

这是一种方法,但它需要 conio.h,这在 Windows 和 DOS 之外通常不可用。它会检查键盘输入,同时还会查看计时器。

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

#define TIMEOUT 10

int main(void)
{
    int code;
    int entry;
    int key;
    time_t mark;
    time_t now;

    mark = time(NULL);
    srand((unsigned)mark);
    code = rand();
    printf("The code is %d\n", code);
    printf("Enter the code\n");
    entry = 0;

    while (entry < code) {
        while (!_kbhit()) {
            now = time(NULL);
            if (now - mark > TIMEOUT) {
                printf("\nTimeout failure!\n");
                exit (1);
            }
        }
        key = _getche();
        entry = entry * 10 + key - '0';
    }

    if (entry == code)
        printf("\nSuccess\n");
    else
        printf("\nIncorrect code\n");

    return 0;
}

程序输出:

The code is 19911
Enter the code
1984
Timeout failure!

更多程序输出:

The code is 20326
Enter the code
29881
Incorrect code

再一次:

The code is 20156
Enter the code
20156
Success

在类似 Unix 的操作系统上,例如 Linux,您可以使用 alarm() 设置计时器,然后从标准输入读取。当定时器超时时,一个 SIGALRM 被传递并且 read 系统调用被中断。您可以通过检查 read 的结果和 errno 的值来观察这种情况的发生。这是您如何执行此操作的粗略示例:

#include <unistd.h>
#include <signal.h>
#include <stdio.h>

void handle_alrm(int signo) {}

/* ... */
ssize_t count;
char linebuf[81];

signal(SIGALRM, handle_alrm);  /* establish a signal handler */
alarm(10);                     /* schedule a SIGALRM in 10 seconds */
count = read(STDIN_FILENO, linebuf, 80);
if (count > 0)
    remaining_time = alarm(0); /* turn off the alarm */
    linebuf[count] = '[=10=]';
    printf("You took %d seconds\n", remaining_time);
    /* do something here ... */
else if (errno = EINTR) {      /* assume the alarm was delivered
    puts("You were too slow!");
    /* do something here ... */
} else {
    /* some other error occured */
    /* do something here ... */
}

signal(SIGALRM, SIG_DFL);

如果您使用 fgets() 而不是 read(),这可能也有效。

另一种不涉及信号的方法是使用select()函数。它允许您在指定的超时时间内等待文件描述符上的数据准备就绪。这可能更适合您的任务,因为它不涉及信号处理。此函数来自 BSD 套接字 API,可能在 Windows 上不可用。它可能是 Winsockets 的一部分。