2015-07-11 98 views
1

在我的节目的开始计算时间我在做一个游戏中,你必须破解像一个系统:类型号码,你在屏幕上看到:12345在10秒内。我想知道如何在10秒过后警告玩家,如在屏幕上打印“太慢!!!!!!”。我尝试了sleep()函数,但它停止了程序,而sleep()函数正在运行!如何开始使用C

规则: 当你启动的程序,出现在屏幕上:

Enter code:   Hack 1. 

如果你输入1,然后输入您似乎有覆盖一个随机数。如果你没有出现:

Hacking failed!!!!!!!!. 

你多慢显得过于它:

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!!!!!!!!!!"); 
      } 
     } 
    } 
} 
+1

你应该阅读有关'for'循环和'while'循环。 – user3386109

+0

您的程序执行必须在等待用户输入时阻止。如果你想打印“太迟了” 10秒后,同时等待有人进入输入你将不得不使用另一个线程 – mathematician1975

+0

一个天真的答案可能是设置一个报警,但是这是很难得到正确。您需要深入了解事件驱动编程的深层复杂领域,并且可能围绕中心事件循环(如epoll和timerfds)构建您的程序。 –

回答

1

这里是做的一种方式,但它需要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 
+1

POSIX无话可说关于'';这是一个仅限于Windows(或者至少是Windows)的头文件。代码可能有Unix端口,但默认情况下它不是Unix(POSIX等)标头。 –

+0

这是一个非常糟糕的想法,因为你正在忙着等待很长一段时间。这导致100%的CPU消耗,直到10秒结束。 – fuz

+0

@JonathanLeffler我提到了POSIX(因为编辑出来了),因为'kbhit()'和'getch()'的MS文档提到了这两个*“这个POSIX函数已被废弃,请使用符合ISO C++的_kbhit(_getch)。 * –

0

在一个类Unix操作系统,如Linux,你将使用alarm()计时器,然后从标准输入读取。当计时器过去时,会发送SIGALRM,系统调用将中断。您可以通过检查的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] = '\0'; 
    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的一部分。