0

私は現在、独学で C と C++ を学んでいます。このちょっとした「プログラムの練習」では、ユーザーに「i」か「d」のどちらかを入力して、整数と 10 進数 (浮動小数点数) のどちらを操作するかを尋ねます。ユーザーが間違った文字を入力したかどうかを伝えることで、ユーザーが「i」または「d」を入力するようにするwhileループがあります。何らかの理由で、while ループ内のプロンプトが getchar() に進む前に 2 回表示されます。この状況でボンネットの下で何が起こっているのかを理解するのに少し苦労しています。どんな助けでも大歓迎です。Xcode を使用しています (関連性があるかどうかはわかりません)。

#include <stdio.h>

int main()
{

  char action;

  printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n"); 

  scanf("%c", &action); 

   while (action != 'i' || action != 'd')
   {
     printf("You didn't entered the right command. Please try again (i/d)\n");
     action = getchar()
   }
 }

したがって、出力として得られるのは次のとおりです。

You didn't entered the right command. Please try again (i/d)
You didn't entered the right command. Please try again (i/d)
4

3 に答える 3

4

文字を入力して改行を押すと、実際には文字と改行文字 ('\n') の 2 つの文字を入力していることになります。ループは文字ごとに 1 回実行されます。これが、2回通過するのを見る理由です。

秘訣は、次のように、戻り文字を明示的に除外することです。

#include <stdio.h>

int main()
{

  char action;

  printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n"); 

  scanf("%c", &action); 

   while (action != 'i' || action != 'd')
   {
     if (action != '\n')
     {
       printf("You didn't entered the right command. Please try again (i/d)\n");
     }
     action = getchar();
   }
}
于 2013-07-26T23:25:28.410 に答える
1

彼の答えでZiffusionによって正しく診断されたように、ユーザーの誤った入力の後に改行を別の文字として取得するため、二重のプロンプトが表示されます。id

いくつかの改善を加えて書き直したものを次に示します。

#include <stdio.h>

int main(void)
{
    char action = '\0';

    printf("Please enter 'i' to work with integers or 'd' to work with decimals: "); 

    while (scanf(" %c", &action) == 1 && action != 'i' && action != 'd')
        printf("You didn't enter the right command. Please try again (i/d): ");

    printf("Action selected: %d\n", action);
}

変更点

  1. プロンプトは改行で終わらないため、ユーザーの応答は改行の直後に表示されます。標準 I/O は通常、標準出力と標準入力を同期させて、プロンプトが改行で終わらなくてもフラッシュされるようにします。プロンプトが表示されない場合は、各プロンプトステートメントの後にfflush(stdout);またはを追加できます。fflush(0);printf()

  2. の結果はscanf()、EOF を処理するためにチェックされます。

  3. の形式にscanf()は先頭のスペースが含まれます。これにより、返される文字の前の空白がスキップされるため、空白でも改行でもない文字が得られます。

  4. 元の条件action != 'i' || action != 'd'は常に真です。&&代わりにが必要です。

  5. Nitpick: エラー メッセージの文法を改善します。

ループの後、アクションは、ユーザーが EOF をトリガーした場合 (入力されたものiまたは同等のもの)ではない可能性があることに注意してください。EOF を取得した場合 (たとえば、ユーザーが からの標準入力を使用してプログラムを実行した場合)、への初期化を除いて、 に決定論的な値はありません。dControl-D/dev/nullaction'\0'

于 2013-07-26T23:57:32.140 に答える