2

我正在制作一个典型的猜谜游戏来学习 C,这是我人生中的第一次,我注意到了一个错误。如果你输入一个整数,你会得到Guess a higher valueorGuess 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

4 回答 4

1

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

于 2012-06-10T12:54:13.060 回答
0

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

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

您有什么可以在此代码中改进的地方吗?

您可能想要改进随机数生成算法。阅读 C 常见问题解答。

于 2012-06-10T12:54:01.677 回答
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;
}

注意里面的ifscanf ("%*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 ()

于 2012-06-10T12:55:11.717 回答
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

于 2012-06-10T14:26:55.500 回答