2017-03-17 40 views
2

我正在C上建立一個測驗項目。我的問題是,我可以使用一個命令或使用一些東西讓用戶決定他是否想繼續回答問題。例如,這裏是我的代碼的一部分。我想使用戶能夠按「0」,並且程序每當用戶按下該按鈕或鍵入時停止。我正在考慮用循環做出,但我想知道是否有反正讓用戶按下一個按鈕或輸入一些東西來結束它,只要他想。 Thansk爲你的時間,併爲我的英語和混亂抱歉。讓用戶輸入一個值後程序停止

#include <stdio.h> 



int main() 
{ 
int a, ep; 
int score; 
score = 0; 

printf("Choose one\n"); 
printf(" 1. Athletics\t 2. History\t\n 3. Internet\t 4. Greek Mythologyn\n"); 
printf("Pick: "); 
scanf("%d",&ep); 

if (ep==1) { 
printf("\n"); 
printf("1. Ποιος διεθνής Έλληνας σκόραρε πάνω από ένα γκολ στο Μουντιάλ 2014;\n"); 
printf(" 1. Παπασταθόπουλος\n 2. Σάμαρης\n 3. Σαμαράς\n 4. Κανένας\n"); 

printf("Answer: "); 
scanf("%d",&a); 

if (a==4) { 
printf("Correct!!!\n"); 
score = score +1; 
} 
else { 
printf("Wrong\n"); 
score = score -1; 
} 
printf("Your score is: %d\n\n\n",score); 

printf("2. Ποιος κέρδισε τον δεύτερο απο τους πέντε τελικούς της σειράς για την Α1 τη\nσεζόν 2013-14;\n"); 
printf(" 1. Ολυμπιακός\n 2. Παναθηναϊκός\n"); 
printf("Answer: "); 
scanf("%d",&a); 
if (a==1) { 
printf("Correct!!!\n"); 
score = score +1; 
} 
else { 
printf("Wrong\n"); 
score = score -1; 
} 
printf("Your score is: %d\n\n\n",score); 
+0

你想用戶停止答題,而他們回答一個問題,他們希望的任何時候? –

+1

如果不在獨立線程中創建類似事件生成器和處理程序的事件,則必須使用連續的用戶提示和響應來提供退出選項或停止測試。 – ryyker

+0

格式化使其很難看清,但列出的示例代碼不完整。它不會編譯。但在下面的答案中有一個完整的版本(寬字符除外)。 – ryyker

回答

2

我想知道是否有無論如何,使用戶按一個按鈕或輸入一些東西來結束它,每當他想。
是的,有。但首先,雖然scanf()是在控制檯應用程序中獲取用戶輸入的一種好方法,例如在示例代碼中,但應注意避免緩衝區溢出,不需要的空白區等。以下鏈接解決了這些問題和其他相關問題。

以及關於控制檯用戶輸入的一種好方法:

建議:
使用一個永遠循環的簡單字符值的測試。此代碼段示出了可以在用戶輸入過程中使用它退出循環,或留在一種技術中的基本要素:

int main() 
{ 
    char c[10]; 
    char go[10]; 
    //Place the rest of your variable declarations and initializations here 

    for(;;) 
    { 
     c[0]=0; 
     //... 
     //The bulk of your code here... 
     //... 
     //Place this section at the bottom of your questions: 
     printf("enter q to exit, or <enter> to continue\n"); 
     fgets(c, sizeof(c), stdin);//reads string input from stdin 
     sscanf(c, " %9s", go);//string 'c' is evaluated according to the 
           //contents of the format string: " %9s" 
           //and parsed into the buffer 'go'. 
           // 
           //Note the space in the format string just 
           //prior to %9s. It causes any white space, 
           //including the newline character, \n, to 
           //be consumed, effectively removing it from 
           //being written into the 'go' buffer. 
           // 
           //The '9' in " %9s" prevents user input beyond 
           //9 characters to be read into the buffer, 
           //thus preventing buffer overflow 
           //and allows room for NULL termination. 
     if(strstr(go, "q")) break;//if 'q' is in string 'go' exit loop 


     //... 

    } 
    return 0; 
} 

您的代碼,基於原來的構建體,的完整版本主要使用sequential flowif(.){...}else(.){...}聲明(包括演示方法中討論的編輯方法)如下。通過使用鏈接中討論的概念,執行流程被改進超過原始。它提示用戶進行測試,以獲取問題的答案,最後提供退出選項。

請注意,這些編輯提供用戶選項,僅在測試結束時退出。底部有一個版本,顯示其他構造選項,包括在程序中任何一點離開的能力。

注意的意見,表示已經作了修改,其中:

int main() 
{ 
    char c[10]; ///added 
    char go[10]; ///added 
    int a, ep; 
    int score; 
    score = 0; 


    for(;;)  ///added 
    {   ///added 
     printf("Choose one\n"); 
     printf(" 1. Athletics\t 2. History\t\n 3. Internet\t 4. Greek Mythologyn\n"); 
     printf("Pick: "); 
     fgets(c, sizeof(c), stdin); //edited 
     sscanf(c, " %d",&ep); //edited 

     if (ep==1) 
     { 
      printf("\n"); 
      printf("1. Ποιος διεθνής Έλληνας σκόραρε πάνω από ένα γκολ στο Μουντιάλ 2014;\n"); 
      printf(" 1. Παπασταθόπουλος\n 2. Σάμαρης\n 3. Σαμαράς\n 4. Κανένας\n"); 

      printf("Answer: "); 
      fgets(c, sizeof(c), stdin); //edited 
      sscanf(c, " %d",&a); //edited 

      if (a==4) 
      { 
       printf("Correct!!!\n"); 
       score = score +1; 
      } 
      else 
      { 
       printf("Wrong\n"); 
       score = score -1; 
      } 
      printf("Your score is: %d\n\n\n",score); 

      printf("2. Ποιος κέρδισε τον δεύτερο απο τους πέντε τελικούς της σειράς για την Α1 τη\nσεζόν 2013-14;\n"); 
      printf(" 1. Ολυμπιακός\n 2. Παναθηναϊκός\n"); 
      printf("Answer: "); 
      fgets(c, sizeof(c), stdin); //edited 
      sscanf(c, " %d",&a); //edited 
      if (a==1) 
      { 
       printf("Correct!!!\n"); 
       score = score +1; 
      } 
      else 
      { 
       printf("Wrong\n"); 
       score = score -1; 
      } 
      printf("Your score is: %d\n\n\n",score); 
     }            ///added 
     printf("enter q to exit, or c to continue\n"); //added 
     fgets(c, sizeof(c), stdin);        //added 
     sscanf(c, " %9s", go);       //added - note space 
                 //in format string 
                 //to consume \n 
                 //character if there 
     if(strstr(go, "q")) break;      //added 

    } 
    return 0; 
} 

備用結構:
的C switch() {...}; statementternary operator。結構被用作改善可讀性的選項。

int main() 
{ 
    char c[10]; 
    char go[10]; 
    int a, ep; 
    int score; 
    score = 0; 
    for(;;)  
    {   
     printf("Categories:\n\n"); 
     printf(" 1. Athletics\t 2. History\t\n 3. Internet\t 4. Greek Mythology\n\n"); 
     printf("Choose a category (or 'q' to exit) : "); 
     fgets(c, sizeof(c), stdin); //edited 
     (isalpha(c[0])) ? 
      (sscanf(c, " %9s",go), ep=0) : 
      (sscanf(c, " %d",&ep), go[0]=0); //using ternary operator -> ?: 
     if(strstr(go, "q")) break; 

     switch(ep) { 
      case 1: 
       // questions for First category 
       printf("Make selection: (or 'q' to exit)\n"); 
       printf("1. Ποιος διεθνής Έλληνας σκόραρε πάνω από ένα γκολ στο Μουντιάλ 2014;\n"); 
       printf(" 1. Παπασταθόπουλος\n 2. Σάμαρης\n 3. Σαμαράς\n 4. Κανένας\n"); 

       printf("Answer: "); 
       fgets(c, sizeof(c), stdin); //edited 
       (isalpha(c[0])) ? 
        (sscanf(c, " %9s",go), a=0) : 
        (sscanf(c, " %d",&a), go[0]=0); //using ternary operator -> ?: 
       if(strstr(go, "q")) break; 

       if (a==4) 
       { 
        printf("Correct!!!\n"); 
        score = score +1; 
       } 
       else 
       { 
        printf("Wrong\n"); 
        score = score -1; 
       } 
       printf("Your score is: %d\n\n\n",score); 

       printf("2. Ποιος κέρδισε τον δεύτερο απο τους πέντε τελικούς της σειράς για την Α1 τη\nσεζόν 2013-14;\n"); 
       printf(" 1. Ολυμπιακός\n 2. Παναθηναϊκός\n"); 
       printf("Answer: "); 
       fgets(c, sizeof(c), stdin); //edited 
       (isalpha(c[0])) ? 
        (sscanf(c, " %9s",go), a=0) : 
        (sscanf(c, " %d",&a), go[0]=0); //using ternary operator -> ?: 
       if(strstr(go, "q")) break; 

       if (a==1) 
       { 
        printf("Correct!!!\n"); 
        score = score +1; 
       } 
       else 
       { 
        printf("Wrong\n"); 
        score = score -1; 
       } 
       printf("Your score is: %d\n\n\n",score); 

       break; 
      case 2: 
       // questions for second category 
       break; 
      case 3: 
       // questions for third category 
       break; 
      case 4: 
       // questions for forth category 
       break; 
      default: 
       printf("Wrong selection. Try again. (1 - 4)\n"); 
       break; 
     } 
     printf("\n\nenter q to exit, or c to continue\n"); 
     fgets(c, sizeof(c), stdin);        
     sscanf(c, " %9s", go);       
     if(strstr(go, "q")) break;      

    } 
    return 0; 
} 
+1

這會造成問題。在每個問題之後,你需要每次都這樣做。 –

+0

我明白,但你需要在每行代碼後。 –

+1

下一次,在輸入一個非q值後,一個換行符仍然會在緩衝區中...而規範的無限循環是'for(;;)' - 較短並且沒有一個常量值布爾值,抱怨。 – Jens

2

一個簡單的事情,你可以使用的是ktbit函數。該功能檢查用戶是否點擊了按鈕。

例子:

int direction = 1; char control; 
while (1) 
{ 
    if(kbhit()){ 
     control = getchar(); 
     switch (control){ 
       case 'x': return 0; 
     } 
    } 
} 

另外,在beginnig,你需要添加#include <conio.h>

+0

這會造成問題。但是由用戶來決定他們是否希望使用此代碼。我只是在提出建議。 @DavidBowling –

+0

從'conio.h'使用'getch()'會自動讓你的代碼** 100%不可移植**,以任何方式通過windoze。使用'stdio.h'中的'getchar()'並將鍵盤置於*非cannonical *模式。 –

+0

謝謝@ DavidC.Rankin –

相關問題