-2

重複の可能性:
ユーザーが数字以外の文字を入力した場合、整数のみをスキャンして読み取りを繰り返す方法は?

こんにちは、私はcを初めて使用し、ユーザーに整数を入力するように求めるプログラムを作成しています.20未満で5より大きいなど、特定の範囲内にあるという基準に一致しない場合は、ユーザーに尋ねます値を再入力します。

しかし、文字を入力するとどうなるのだろうと思ったら、まあ無限ループが発生します。

したがって、入力された値をチェックして正しいデータ型であるかどうかを確認する方法または特定の関数があることを知りたいです。そして、私はユーザーに再プロンプトしません。

4

6 に答える 6

6

多くの人が試みましたが、ユーザーの脳を制御して、ユーザーが時々間違った (種類の) ボタンを押すのを防ぐコンピュータを作ることに成功していません... ;)

これを解決するには、一般的に受け入れられている 2 つの解決策があります。

  1. 「エコーなし」で読み取り、不正な入力を破棄する直接入力関数を書きます [おそらく何らかのメッセージが表示されます]、および有効な入力が何であるかを「知る」特定の入力関数。

  2. 標準関数を使用して入力をテキスト文字列として読み取り、文字列入力を数値などに変換/検証します。ここで、変換/検証が失敗した場合、何らかのメッセージを出力して、ユーザーに再試行するように求めます。

于 2012-12-31T16:56:03.433 に答える
5

この可能性に対抗するには、入力をテキストとしてスキャンし、自分でサニティ テストを行う必要があります。

于 2012-12-31T16:47:09.883 に答える
2

で読み取ることができscanf("%d")、ユーザーが数字以外の文字を含む文字列を入力した場合は、で再度読み取る前に stdin バッファーを消去する必要がありますscanf("%d")

標準入力を消去すると、無限ループが停止します

次の関数を使用して、標準入力を消去します

int clean_stdin()
{
    while (getchar()!='\n');
    return 1;
}

また、stdin からの整数の読み取りは、次の方法で行うことができます。

char c;
do
{  
    printf("\nEnter an integer from 5 to 20: ");

} while (((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin()) || rows<5 || rows>20);
于 2012-12-31T16:59:50.347 に答える
1

strtol一般的な方法は、入力をテキストとして読み取り、またはのようなライブラリ関数を使用してターゲットの型に変換することstrtodです。これらの関数は両方とも、不正な入力を検出することもできます。

1 つのアプローチを次に示します。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
  char instr[12];
  int  value;
  char *chk;

  /**
   * Make sure read is successful
   */
  errno = 0;
  if (!fgets(instr, sizeof instr, stdin))
  {
    perror("Unable to read input string");
    exit(-1);
  }

  /**
   * Make sure user didn't enter more characters
   * than we're prepared to handle.
   */
  if (!strchr(instr,'\n'))
  {
    fprintf(stderr, "Input too long for buffer, discarding...\n");
    while (!strchr(instr,'\n'))
      fgets(instr, sizeof instr, stdin);
     exit(-1);
  }
  else
  {
    *strchr(instr,'\n') = 0;
  }


  /**
   * Convert text to decimal integer using strtol
   */
  value = (int) strtol(instr, &chk, 10);
  if (!isspace(*chk) && *chk != 0)
  {
    fprintf(stderr, "%s\n", instr);
    fprintf(stderr, "%*s^\n", (int)(chk - instr), " ");
    fprintf(stderr, "Invalid character detected in input string\n");
    exit(-1);
  }

  printf("Converted input value is %d\n", value);
  return 0;
}

したがって、読み取りエラーがなく、ユーザーが不快なほど長い入力を入力しなかったと仮定すると、 を使用strtodしてテキスト文字列を対応する整数値に変換します。 chk有効な整数定数の一部ではない最初の文字を指すように設定されます。その文字が空白文字 ( isspace(*chk)) または 0 ターミネータでない場合、入力は有効な整数文字列ではありませんでした。その後、それを捨てて、新しい入力を求めることができます。

于 2012-12-31T19:19:39.087 に答える
0

<ctype.h>Cのヘッダーにはいくつかの関数があります..

isalpha()入力された入力がアルファベットかどうかをチェックするために使用されます。

文字列で入力を取得し、各文字がアルファベットか数字かを確認できます.ループに入れて確認し、指定された入力が有効でない場合はユーザーに再入力を求めます..

isdigit()指定された入力が数字かどうかをチェックするために使用されます。

int is_alpha(char *s)
{
    while(*s) {
      if(isalpha(*s))
            s++;
        else 
            return 0;
    }

        return 1; 
   }

上記の関数は、入力された入力がすべてアルファベットかどうかをチェックします。条件が失敗した場合は「0」を返し、条件が偽の場合は「1」を返します。

main 関数で戻り値を収集し、確認します。

于 2012-12-31T16:52:10.510 に答える
-1

入力された数字が整数か、入力された文字が実際にazの間にあるかどうかを確認できる関数は存在します。

ただし、特定の範囲に設定できる機能はありません。独自に設計する必要があります。単純な関数は次のようになります

int check(int a)
{
if(a>5 && a<20)
{
printf("Need a different Value");
}
}
于 2012-12-31T16:54:44.350 に答える