2015-07-11 73 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的一部分。