2

私は生まれて初めて C を学ぶために典型的な当てっこゲームを作っていて、バグに気づきました。整数を入力すると、Guess a higher valueorが得られGuess 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

入力が数値かどうかをチェックする関数を作成したい場合があります。お気に入り:

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 に答える
0

私が今やろうとしているのは、ユーザーが文字列を入力したかどうかを確認することです。テキストではなく数値を入力してください。どうすればいいですか?

scanfフォーマットされた入力を行います。scanfまた、入力の一部を無視する、文字列を読み取るためのバッファ サイズを指定する、読み取りたい特定の文字セットのみを指定するなど、高度な書式指定子をチェックアウトすることもできます。入力を確認したい場合は、おそらく、使用してコンソールから行を読み取り、その行をfgets解析するのが最善です。

このコードで改善できる点はありますか?

乱数生成アルゴリズムを改善したい場合があります。C FAQ を読んでください。

于 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;
}

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

于 2012-06-10T12:55:11.717 に答える