C - 用户单个字符输入呈现奇怪的结果

Jam*_*nes 5 c input char clear

新来的,我有一个非常简单的问题.我在C中制作一个简单的程序,要求用户输入如何处理char的选择.输入结果后,程序返回菜单.然而,它似乎采取某种鬼输入,好像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);
}
Run Code Online (Sandbox Code Playgroud)

这是一个示例输出:

- - - 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
Run Code Online (Sandbox Code Playgroud)

输入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;
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*ike 4

看来您已经有了答案,并且检查一下,它是正确的;使用getchar()将从中读取一个字符stdin

printf("Enter choice: ");
menu_choice = getchar();
Run Code Online (Sandbox Code Playgroud)

当我在控制台出现此提示并键入时,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();
}
Run Code Online (Sandbox Code Playgroud)

会向您展示:

You entered
 (10).
That's an invalid choice.
Run Code Online (Sandbox Code Playgroud)

事实上它位于不同的行,并且根据 ASCII 表检查十进制结果,您会发现 10 10是换行符,这可以帮助您得到结果。

编辑:

1 个用于使用换行符的选项 -

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

第二个选择:

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
Run Code Online (Sandbox Code Playgroud)

如果您只想获取字符然后以 & 结尾'\n',则必须添加并转义换行符:

printf("what character?");
scanf("%c\\n", &c); 
Run Code Online (Sandbox Code Playgroud)