5

5 行目で整数を読み取り、整数を読み取るisint場合は 1 を取得し、整数でない場合は 0 を取得します。が 0 の場合isint、ユーザーに整数を与えるように求めるループがあり、ユーザーが整数を与えるまで読み取ります。整数の代わりに文字を指定してこのコードを試してみましたが、無限ループが発生しました。プログラムは、新しい入力を待つだけではありません。コードの何が問題になっていますか?

#include <stdio.h>

int main(void) {

  int arg1;
  //int arg2;
  int attacknum = 1;
  int isint = 1;

  //printf("Insert argument attacks and press 0 when you have done this.\n");
  printf("Attack %d\n", attacknum);
  attacknum++;
  printf("Give attacking argument:");
  isint = scanf("%d", &arg1);  //line 5

  while(isint == 0){
    printf("You did not enter a number. Please enter an argument's number\n");
    isint = scanf("%d", &arg1);
    printf("is int is %d\n", isint);
  }
  return 0;
}
4

2 に答える 2

13

他の人が述べたようにscanf、入力を解析できない場合、スキャンされないままになります。

この種の動作と、ユーザーが経験する一度に 1 行ずつのインターフェイスと一致しないため、通常scanf、対話型入力には適していません。

を使用して 1 行をバッファに読み込む方がよいでしょうfgets。次に、を使用してその行を解析しsscanfます。入力が気に入らない場合は、行全体を破棄して別の行を読んでください。

このようなもの:

#include <stdio.h>

int main(void)
{
  char line[256];

  int arg1;
  int isint;

  while (1) {
    printf("Give attacking argument:");
    fgets(line, sizeof line, stdin);
    isint = sscanf(line, "%d",&arg1);
    if (isint) break;

    printf("You did not enter a number.Please enter an argument's number\n");
  }

  printf("Thanks for entering %d\n", arg1);

  return 0;
}

(製品コードの場合、長い行を処理したり、リターン コードをチェックしたり、数値の後に続くゴミをチェックしたりする必要があります。)

実際には、整数を読み取るだけの場合は を使用せずscanfstrtol、代わりに を使用することをお勧めします。これにより、数字の直後の文字への便利なポインターが得られ、それが空白またはヌルであることを確認できます。

于 2013-06-02T12:01:49.027 に答える
4

scanf数字以外に直面すると、入力を消費せず、ゼロの整数が読み取られたことを返します。数字以外は、次の呼び出しの入力に残りscanf、最初の呼び出しと同じように動作します。

以下の質問への回答です。fgetcを使用して少なくとも 1 文字を解析できますが、これにより、既に入力されたすべての文字のエラー メッセージが表示されます。通常、改行までスキップしたいと思います。fgetsこの目的のために、プーリーの提案に従って使用できます。または、 の後に次を追加することもできますscanf

int ch;
if (isint == 0)
while ((ch = fgetc(stdin)) != EOF && ch != '\n')
{
     /* Skip characters */
}

printfPS:あなたの場合、ループの最初の直前に置く方がおそらく良いでしょう。

于 2013-06-02T11:57:27.250 に答える