5

ここで初めて、非常に簡単な質問があります。私は、ユーザーが char をどうするかの選択を入力する必要がある C で簡単なプログラムを作成しています。結果を入力すると、プログラムはメニューに戻ります。ただし、char に不明な値があるかのように、ある種のゴースト入力が必要なようです。char をデフォルトの状態に戻す必要があります。

コード:

/* display menu for user */
void menu() {

    printf("\n- - - Phone Book Database - - -\n");
    printf("\nSelect an action:\n\n");
    printf("\tc:\tCreate a database entry.\n");
    printf("\ts:\tSearch the database entries.\n");
    printf("\td:\tDelete a database entry.\n");
    printf("\tq:\tQuit program.\n\n");

    printf("Enter choice: ");
    menu_choice = getchar();

    if(menu_choice != 'c' && menu_choice != 's'
        && menu_choice != 'd' && menu_choice != 'q') {
            printf("\n\n\tInvalid choice.\n");
            menu();
    }
    //fflush(stdin);
}

出力例を次に示します。

- - - Phone Book Database - - -

Select an action:

    c:  Create a database entry.
    s:  Search the database entries.
    d:  Delete a database entry.
    q:  Quit program.

Enter choice: c

Enter name: test

Enter address: test

Enter number: 3

- - - Phone Book Database - - -

Select an action:

    c:  Create a database entry.
    s:  Search the database entries.
    d:  Delete a database entry.
    q:  Quit program.

Enter choice: 
    Invalid choice.

- - - Phone Book Database - - -

Select an action:

    c:  Create a database entry.
    s:  Search the database entries.
    d:  Delete a database entry.
    q:  Quit program.

Enter choice: q

入力として c を入力すると、次の関数が呼び出されます

/* creates a new record in array */
void create_record() {
    char name[MAX];
    char address[MAX];
    int number;

    rec_num++; /* add 1 to marker for record placement */

    printf("\nEnter name: ");
    scanf("%s", name);

    printf("\nEnter address: ");
    scanf("%s", address);

    printf("\nEnter number: ");
    scanf("%d", &number);

    strcpy(record[rec_num].name, name);
    strcpy(record[rec_num].address, address);
    record[rec_num].number = number;
}
4

4 に答える 4

4

あなたはすでに答えを持っているように見えますが、見直してみると正しいです。を使用getchar()すると、から1文字が読み取られますstdin

printf("Enter choice: ");
menu_choice = getchar();

コンソールでこのプロンプトに到達して入力すると、c<enter key>2 つの文字がstdin:'c''\n'

初めてgetchar();実行すると'c'、改行文字だけが取得されます。2 番目の反復で'\n'は、ユーザーから何も待たずに が取得されます。したがって、「ゴースト入力」があるようです。

ユーザーからの入力を取得していて、結果が期待したものではない場合はいつでも、何が起こっているかを確認するためにそれをダンプしても害はありません。たとえば、次のようになります。

if(menu_choice != 'c' && menu_choice != 's'
    && menu_choice != 'd' && menu_choice != 'q') {
        printf("\n\n\tYou entered %c (%d).\n", menu_choice, menu_choice);
        printf("\tThat's an invalid choice.\n");
        menu();
}

あなたに示したでしょう:

You entered
 (10).
That's an invalid choice.

それが別の行にあったという事実と、その 10 進数の結果を ASCII テーブルと照合してチェックすると、10 10が改行文字であることがわかり、結果を導き出すのに役立ちます。

編集:

改行を消費するための 1 つのオプション -

printf("what character?");
c = getchar(); // Get the character from stdin
getchar();     // consume the newline character that was left

2 番目のオプション:

printf("what character?");
scanf("%c ", &c); // Get the character from stdin, note the space after the %c
                  // that will allow any special characters including \t and \n

文字を取得してから で終了して消費したい場合は'\n'、改行文字を追加してエスケープする必要があります。

printf("what character?");
scanf("%c\\n", &c); 
于 2012-12-04T18:09:43.183 に答える
2

他の人が指摘しているように、それは改行文字です。もう一つ追加するだけ

(void) getchar(); /* read and discard newline */

1文字だけ読みたいところならどこでも。

于 2012-12-04T18:32:33.323 に答える
0

戻り文字 '\n' はおそらく残されstdinているため、次に来たときにこれgetchar()をフェッチします。

getchar()デバッガーを使用するか、単に出力して、フェッチされた値を調べてみてください。

getchar()それはあなたのアプリケーションにとっては良い選択ではないかもしれませんが、それscanf()はより良い仕事をするでしょう。そうすれば、すべての stdin がフェッチされ、次回あなたが来たときに空になるはずです。明らかに、他のコードと同様に、scanf に複数の文字を書き込む必要があります。

次に、配列の最初の文字を見て、文字を取得できます。

于 2012-12-04T17:35:45.280 に答える
-1

入力コマンドの後に入力バッファーに迷走文字 (ほぼ確実に '\n') が残ります。

それを削除するには、次を追加できます。

fflush(stdin)

getchar()...あなたの電話の直前に。

于 2012-12-04T17:13:17.997 に答える