随机猜谜游戏(整数) - 输入字符串时的错误

时间:2012-06-10 12:46:45

标签: c string random numbers

我正在制作一个典型的猜谜游戏,以便在我的生命中第一次学习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;
    }
    

4 个答案:

答案 0 :(得分:1)

您忽略了scanf的返回值,它会告诉您转换是否顺利。 scanf将返回分配的项目数,因此如果它返回1,您就知道answer已分配给某个数字。如果它返回0,你就知道出了问题。

答案 1 :(得分:0)

  

我现在要做的是检查用户是否输入了   字符串,它会对用户说一些输入数字,而不是   文本。我该怎么做?

scanf执行格式化输入。您可能还想查看scanf中的高级格式设置说明符 - 例如忽略输入的部分,指定用于读取字符串的缓冲区大小,仅指定要读取的特定字符集等。如果您想要验证输入,您可能最好使用fgets从控制台读取一行,然后解析该行。

  

您是否看到我可以在此代码中进行改进?

您可能希望改进随机数生成算法。阅读C FAQ。

答案 2 :(得分:0)

检查scanf的返回值。它将返回成功匹配和分配的项目数。在这种情况下,如果输入一个字符串,那么它将不会被匹配和分配,但是字符串保留在输入缓冲区中,并且scanf尝试在每次迭代中读取它并失败,因此出现问题。 / p>

您可以将代码更改为:

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 ()

答案 3 :(得分: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