2012-06-10 57 views
2

我正在做一個典型的猜謎遊戲,以便在我的生活中第一次學習C,並且我注意到了一個錯誤。如果你輸入一個整數,你會得到Guess a higher valueGuess a lower value,這工作得很好。但是,如果你放入一個字符串,它會變得瘋狂,並打印出很多字符串,說Guess a higher value隨機猜測遊戲(整數) - 輸入字符串時的錯誤

  1. 什麼我想現在要做的是做一個檢查,如果用戶輸入一個字符串,它會說用戶有點像Enter a number, not text。我該怎麼做呢?

  2. 有什麼你看到我可以在這個代碼中改進?

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <time.h> 
    int main() { 
    
        int secret, answer; 
    
        srand((unsigned)time(NULL)); 
    
        secret = rand() % 10 + 1; 
    
        do { 
         printf ("Guess a number between 1 and 10"); 
         scanf ("%d",&answer); 
         if (secret<answer) puts ("Guess a higher value"); 
         else if (secret>answer) puts ("Guess a lower value"); 
        } while (secret!=answer); 
    
        puts ("Congratz!"); 
        return 0; 
    } 
    
+2

這是C,而不是C++。 –

+0

相應地更改標籤(C不是C++)。 –

+0

噢,這是?那麼......這個例子不是很簡單嗎? C和C++不是很相似嗎?這個例子在兩種語言中並不是那麼不同。 – user1431627

回答

0

什麼我想現在要做的是,使對於如果用戶輸入一個字符串 的檢查,它會說用戶有點像輸入一個數字,不 文本。我該怎麼做呢?

scanf確實格式化輸入。您可能還想查看scanf中的高級格式化說明符 - 例如忽略輸入的部分內容,指定用於在字符串中讀取的緩衝區大小,僅指定要讀取的特定字符集等。如果要驗證輸入,您可能最好是使用fgets從控制檯讀取一行,然後解析該行。

有什麼你看到我可以在這個代碼中改進?

您可能想要改進您的隨機數生成算法。閱讀C FAQ。

1

您忽略了scanf的返回值,它會告訴您轉換是否順利進行。 scanf將返回分配的項目數量,因此如果返回1,則知道answer已分配給一個數字。如果它返回0,你就知道出了點問題。

+0

當我停止我的應用程序時它返回0。 – user1431627

+0

然後您知道用戶沒有輸入虛擬號碼。打印錯誤消息並再次提示用戶。 – JesperE

0

檢查返回值scanf。它將返回成功匹配和分配的項目數量。在這種情況下,如果輸入一個字符串,那麼它將不會被匹配和分配,但字符串保留在輸入緩衝區中,並且scanf會嘗試在每次迭代中讀取它並失敗,從而出現問題。

您可以更改代碼:

int main() { 

    int secret, answer; 

    srand((unsigned)time(NULL)); 

    secret = rand() % 10 + 1; 

    do { 
     printf ("Guess a number between 1 and 10"); 
     if (scanf ("%d",&answer) != 1) 
     { 
     printf ("\nPlease enter an integer\n\n"); 
     scanf ("%*s"); 
     continue; 
     } 
     if (secret<answer) puts ("Guess a higher value"); 
     else if (secret>answer) puts ("Guess a lower value"); 
    } while (secret!=answer); 

    puts ("Congratz!"); 
    return 0; 
} 

注意,if裏面的線scanf ("%*s");完成。在%*s中,*是輸入壓縮指示符,這表示將讀取一個字符串(代表%s),但*表示儘管字符串將從輸入中讀取,但將被丟棄。這是爲了簡單地丟棄之前輸入的字符串而不被scanf ("%d",&answer)讀取。如果不放棄緩衝區中的字符串,它將保持不變,並且每次迭代scanf ("%d",&answer)將無法​​匹配任何整數,因爲它將遇到輸入緩衝區中的剩餘字符串。

另一方面,您可能會讀取一個字符串並將字符串轉換爲整數。

像如下:

int main() { 

    int secret, answer; 
    char buff[128]; 

    srand((unsigned)time(NULL)); 

    secret = rand() % 10 + 1; 
    do { 
     printf ("Guess a number between 1 and 10"); 
     scanf ("%s",buff); 
     if ((answer = atoi (buff)) == 0) 
     { 
      printf ("\nPlease enter an integer\n\n"); 
      continue; 
     } 
     if (secret<answer) puts ("Guess a higher value"); 
     else if (secret>answer) puts ("Guess a lower value"); 
    } while (secret!=answer); 

    puts ("Congratz!"); 
    return 0; 
} 

atoi()將一個字符串轉換爲一個整數(在10個鹼基)。如果包含整數的字符不包含有效數字,則將返回0。檢查它我們可以檢測用戶輸入是否正確。此外,因爲您的應用程序需要輸入1到10之間的整數,因此不包含0,因此可以將0作爲無效。要獲得檢測無效整數格式更好的控制,並在字符串中錯誤的位置使用strtol()

+0

當我使用你的代碼時,程序將無法正常工作。它總是說'猜測一個較低的值,但從1到10沒有任何值。我嘗試了所有可能的數字1,2,3,4,5,6,7,8,9,10。 – user1431627

+0

我無法重現您遇到的錯誤。哪個編碼上面的一個或下面?第一個代碼是 – phoxis

+0

。編輯:現在檢查:下面的一個也不工作。它只是說我需要一個較低的數字。 – user1431627

0

你可能想使一個函數來檢查,如果輸入的是數字。像:

int isNumeric(char *str){ 
    while(*str) 
    { 
    if (!isdigit(*str)) 
     return 0; 
    str++; 
    } 
    return 1; 
} 

int main(){ 
    char guess[3]; 
    int iGuess; 
    do { 
     printf("Guess a number between 1 and 10"); 
     gets(guess); 
     if (!isNumeric(guess)){ 
     printf("Invalid input"); 
     continue; 
     } 
     iGuess = atoi(guess); 
    if (iGuess<secret) 
      printf("Higher"); 
    else if (iGuess>secret) 
      printf("Lower"); 
    } while (secret!=iGuess); 
    printf("Congrats"); 
    return 0; 
} 

您需要包括文件ctype.h和STRING.H

+0

它不工作。同樣的問題。 – user1431627