5

新来的,我有一个非常简单的问题。我正在用 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

看起来您已经有了答案,并且复习一下,它是正确的;usinggetchar()将从中读取一个字符stdin

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

当我在控制台上看到此提示并键入c<enter key>时,会导致两个字符转到stdin'c''\n'

第一次getchar();运行时,它只拾取'c'离开的换行符。在第二次迭代中'\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.

在它位于不同行的事实和根据 ASCII 表检查十进制结果之间,您会看到 10 10是换行符,这可以帮助您获得结果。

编辑:

使用换行符的 1 个选项 -

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

第二种选择:

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 */

您只想阅读一个字符的地方。

于 2012-12-04T18:32:33.323 回答
0

return char '\n' 可能会被留在stdin里面,这样下次你来的时候它getchar()就会获取这个。

getchar()尝试使用调试器或打印出来查看获取的值。

对于您的应用程序来说,这可能getchar()不是一个很好的选择,并且scanf()会做得更好,这样所有标准输入都将被获取,并且下次您来时它应该是空的。显然,您还需要为 scanf 提供多个要编写的字符,就像在您的其他代码中一样。

然后,您可以简单地查看数组中的第一个字符来获取您的字符。

于 2012-12-04T17:35:45.280 回答
-1

在您输入命令之后,一个杂散字符(几乎可以肯定是 '\n')会留在您的输入缓冲区中。

要删除它,您可以添加:

fflush(stdin)

...就在您getchar()打电话之前。

于 2012-12-04T17:13:17.997 回答