0

Webから編集したコードからの単純な通貨コンバータープログラムと、入力したswitchステートメントをまとめました。VisualStudioでプログラムを実行すると、次のようになります。

printf("Would you like to make another conversion? y/n\n");
fflush(stdin);
scanf("%c",&marker);

入力を待ってから、whileステートメントの先頭に戻るか、コンソールウィンドウを終了します。これを実行すると、これはMacでXcodeになります。「別の変換を行いますか...」が出力されますが、入力を待たずに、whileループに戻ります。

printf( "Would you like ... etcセクションを適切な場所に配置しますか?または、ユーザーからの入力を受け取った後にループを再度実行するためのより良い方法はありますか?'boolで何かを行う必要がありますか? 'ステートメント。クラスではまだそれほど進んでいません。

完全なコードを以下に示します。

#include <stdio.h>

int main ()
{
int choice;
float money;
float total;
char marker='y';

printf("\n\nCURRENCY CONVERSION\n");
printf("***Rates correct as of 26 NOV 12***\n");
printf("------------------------------------\n");
printf("1. Australian Dollar (AUD) 1.533=1 GBP\n");
printf("2. Euro (EUR) 1.235=1 GBP\n");
printf("3. Indian Rupee (INR) 89.494=1 GBP\n");
printf("4. Japanese Yen (JPY) 131.473=1 GBP\n");
printf("5. US Dollar (USD) 1.602=1 GBP\n");
printf("Enter the number for the currency to convert...");

while(marker!='n')
{
    printf("\n\nWhat would you like to convert your money to? (1-5): ");
    scanf("%d",&choice);

    printf("\n\nHow much money do you want to convert? (GBP): ");
    scanf("%f",&money);

    switch(choice) {
        case 1:
            total = money * 1.533;
            printf("\n\nYou will have %.2f Australian Dollars \n\n", total);
            break;
        case 2:
            total = money * 1.235;
            printf("\n\nYou will have %.2f Euros \n\n", total);
            break;
        case 3:
            total = money * 89.494;
            printf("\n\nYou will have %.2f Indian Rupees \n\n",total);
            break;
        case 4:
            total = money * 131.473;
            printf("\n\nYou will have %.2f Japanese Yen \n\n", total);
            break;
        case 5:
            total = money * 1.602;
            printf("\n\nYou will have %.2f US Dollars \n\n", total);
            break;
        default:
            printf("You did not choose a correct option\n");
    }

    printf("Would you like to make another conversion? y/n\n");
    fflush(stdin);
    scanf("%c",&marker);
}
return 0;
}

寄せられた意見のコメントに感謝します。

4

4 に答える 4

2

あなたの問題はscanf("%c", &marker);、以前の入力によって残された改行を が読み取っている可能性があります。

fflush(stdin)未定義の動作を呼び出すことに注意してください。C標準は次のように述べていfflush()ます:

stream が、最新の操作が入力されていない出力ストリームまたは更新ストリームを指している場合、fflush()そのストリームの未書き込みデータがファイルに書き込まれます。

その操作が Visual Studio または Windows の入力キューをクリアする場合、あるプラットフォームの標準に対する拡張機能が他のプラットフォームでは常に機能するとは限らないという難しい方法を学習したことになります。特に、fflush(stdin)キューに入れられた読み取り待ちの文字はクリアされません。

エラーメッセージの一部として誤った入力を出力することで、デバッグ作業を支援できたことに注意してください。


scanf()また、各呼び出しをテストする必要があります。

if (scanf("%c", &marker) != 1)
    ...EOF or other problem...

if (scanf("%f", money) != 1)
    ...EOF or maybe a letter instead of a number...

スタイル的には、スイッチbreak;のラベル​​の後のコードの後に​​ a を含めるのが最善です。default:

また、メニューに表示される文字列と case ステートメントでコンバージョン率を繰り返さないようにする必要があります。通貨名も同様です。配列と構造体をまだカバーしていないかもしれませんが、長期的には、それは問題のレシピです (レートが変更されたために再コンパイルが無駄になっただけの場合; しかし、それらをファイルまたは Web サイトから読み取ることができるようにすることは重要です)。別の主要な演習)。

于 2012-11-26T21:38:31.957 に答える
2

これはループとは関係ありません。それはscanfへのあなたの呼び出しについてです。

何が起こっているかというと、標準入力がバッファリングされているということです。scanf は、バッファーに保留中のデータが十分にない場合にのみ、プログラムを停止して入力を待機させます。これを行う場合:

scanf("%f", &f);

...その後、テキスト行を入力するまでプログラムは停止します。次のように入力するとします。

1\n

1 は変数 f... に読み込まれますが、改行は buffer に残ります

これは、次への呼び出しを意味します。

scanf("%c", &c);

...呼び出しを完了するのに十分なデータがバッファーにあるため、すぐに戻ります。プログラムは、バッファが不足した場合にのみ停止し、次のデータを待ちます。

Windows はこのようなバッファリングを行いません。そのため、そこでの動作を観察していませんでした。

これには、stdin のバッファリング方法の変更から、ncurses のようなテキストベースの UI ライブラリの使用まで、約 100 万の解決策があります。デフォルトで stdin が行バッファリングされていることを考えると --- データは一度に 1 行ずつ読み取られ、改行で終了します --- 最も簡単なのは、 の各呼び出しscanf()がテキストの完全な行を消費することを確認することです。これは、scanf を呼び出すたびにバッファーが空になることを意味します。例えば:

scanf("%f\n", &f);

...と:

scanf("%c\n", &c);

ユーザーがこのフォーマット文字列に一致しない入力を入力した場合 ( 1 21 番目または2 番目など)、 scanfabは変数を初期化しないままにすることに注意してください。したがって、必ず戻りパラメータを確認する必要があります。

if (scanf("%f\n", &f") != 1)
    error("Oh noes!");

そうしないと、あなたのプログラムは恐ろしく、恐ろしく間違ったものになってしまいます。

余談ですが、このプログラムでは実行していませscanf("%s")んが、使用しないでください。何でも。

于 2012-11-26T21:48:48.467 に答える
0

無限ループ (例: while(true){} ) を実行できます。switch ステートメントには、ループを中断する選択肢 'n' のケースがあります (例: break;)。

また、ケース 1 、ケース 2 など...整数ではなく文字としてスキャンします。(例: ケース '1':、ケース '2': など...)

今言ったことがうまくいくかどうかはわかりませんが、それが私の最初の考えです。それが役に立てば幸い :)

于 2012-11-26T21:37:59.773 に答える
0

フラッシュ バッファを処理したくない場合は、 a を定義して、次のchar buffer[1024]ように使用fgetsできsscanfます。

printf("\n\nWhat would you like to convert your money to? (1-5): ");
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &choice);

while ループにはメニューを含めることができます。

while (1) {
  printf("\n\nCURRENCY CONVERSION\n");
  printf("***Rates correct as of 26 NOV 12***\n");

  /* ... */

  printf("Would you like to make another conversion? y/n\n");
  fgets(buffer, sizeof(buffer), stdin);
  sscanf(buffer, "%c", &marker);
  if (marker == '\n')
    break;
}
于 2012-11-26T21:48:09.437 に答える