2017-02-05 6 views
1

文字を入力すると、ループが無限に実行されます。文字がintとして入力されたときにゼロとして格納されますか?非数字回答を拒否することはできますか?範囲外の回答を拒否しましたか?ただ、背景Cでintを要求するときに拒否する方法

ため

int main(int argc, const char * argv[]) { 
// insert code here... 

int categoryToScore; 
int categoryScores = 6; 

printf("Enter category to save score: "); 
scanf("%d", &categoryToScore); 

while (categoryToScore >= categoryScores || categoryToScore <= 0) { 
    printf("Error: invalid command. Enter 1-5 to save to an unused category\n"); 
    printf("Enter category to save score: "); 
    scanf("%d", &categoryToScore); 
} 

return 0; 

}

私がしたい:

  1. 印刷要求の入力のためのscanf
  2. 1〜上限である入力
  3. 入力が正しいタイプで正しい範囲内にあるかどうかを確認してください
  4. それは、エラーメッセージを出力し、その後、あなたは、標準入力から数を読み取るためのscanfを求めている
+1

scanfのは、値を返します - 成功し、スキャン要素の数 - 引数が指すものは何でもに落書きに加えを。有効な番号でないものを入力したときに戻り値をチェックすると、0になるはずです。 –

+1

また、 'scanf()'が無効な入力のために失敗した場合、再試行する前に何らかの形で無効な文字をクリア(読みとり)しなければなりません。 – Dmitri

+0

無効な文字(文字)が入力されたときにそれが保存され、scanfがその文字を読み込むと、ループがscanfに戻ったら同じ文字をもう一度読み込むのですか?これを避けるために、scanfがチェックしている領域をクリアする必要があるので、スキャンする前に別の入力が必要ですか? –

答えて

2

続行されている場合1.

  • に戻っていない場合。 Scanfは標準入力で数字以外の文字を見つけ、はそれを標準入力から削除しません。 Scanfが失敗し、0(正常に処理されたフィールドの数)が返されます。

    次回scanfを呼び出すと、標準入力の開始時に同じ文字が検索されます。このプロセスは無期限に繰り返されます。

    1つの解決方法は、一度に1文字ずつ標準入力を読み取ることです。

    もう1つの解決策は、scanfをもう一度呼び出す前にstdinから1文字を読み込み(そして破棄する)ことです。

  • +0

    返信ありがとうございます。私は 'getc()'が新しく、このアプローチを使用するとエラーが発生します。 "関数呼び出しへの引数が少なすぎる、1になると0が返される" –

    +0

    @AlexButterfield getc()の代わりにgetchar()を使用する。私は答えを修正しました。 – George

    0

    この特定のプログラムを修正するのではなく、「終了条件」という概念を使用して同様の問題を解決する方法を示します。

    終了条件の考え方は、無限ループがあり、さまざまな終了条件があることです。多くの場合、正常終了とエラーの2つの終了条件があります。

    while(true){ /* infinite loop */ 
        char c = ... /* get the character you want */ 
        if(c < '0' || c > '9'){ 
         printf("invalid character, not a digit\n"); 
         continue; // get another character 
        } 
        ... /* do whatever you with valid data */ 
        if(c == '3') break; /* your exit condition, whatever it is */ 
        if(c == '7') exit(0); /* exit the whole program */ 
    } 
    

    注:フリーフォームの入力(数字と文字列)を受け入れている場合は、scanf関数はおそらく良いアイデアではありません。 scanfは、非常に特殊な形式の入力を受け入れます。したがって、%dを求める場合は、入力に%d(10進数)を入れることをお勧めします。そうしないと問題が発生します。

    たとえば、数字と文字列を受け入れる場合は、fgetsなどを使用してすべてを文字列として取得する必要があります。ここで


    は何をしたいん完全なプログラムです:

    #include <stdio.h> 
    #include <stdbool.h> 
    
    int main(int argc, const char * argv[]) { 
        int iMaxScore = 6; 
        int charInput = 0; 
        int iInputValue = 0; 
    
        while(true){ 
         printf("Enter category to save score: "); 
    GetInput: 
         charInput = getchar(); 
         if(charInput == 10 || charInput == 13) goto GetInput; /* ignore enter key */ 
         if(charInput == 'q') break; 
         if(charInput < '0' || charInput > '9'){ 
          printf("invalid entry, not a digit %d\n", charInput); 
          break; 
         } 
         iInputValue = charInput - '0'; 
         if(iInputValue > iMaxScore){ 
          printf("Error, input value exceeds maximum category %d\n", iMaxScore); 
          continue; /* try again */ 
         } 
         printf("you entered category %d\n", iInputValue); 
         /* continue ... */ 
        } 
    
        return 0; 
    } 
    
    +0

    私は今このアプローチを試みました。私は 'exit(0)'にエラーがあったので、それを使わずに試してみました。数字の代わりに文字を入力すると同じ無限ループ動作になります –

    +0

    @AlexButterfieldこれはおそらくscanf )。通常、scanf()は個々の文字ではなく、構造化された入力レコード全体を読み込むために、%dの場合の10進整数である "レコード"を取得するまで待っています。おそらく文字が必要な場合は、getchar()を試してみてください。これについてのSOの質問があります:http://stackoverflow.com/questions/2507082/getc-vs-getchar-vs-scanf-for-reading-a-character-from-stdin –

    +0

    @AlexButterfield私はいくつかのニュアンスがあることを認識しています改行文字やそのようなものを扱っているので、私はプログラム全体を作り始めました。無限ループをどのように使用しているのかを知ってから、さまざまな終了条件を設定するとよいでしょう。 –

    関連する問題