使用 fgetc(stdin) 多次输入后重复打印消息

Repeated printing of message after multiple input with fgetc(stdin)

我正在编写一个具有 2 个功能的程序。当他打开程序时,要求用户通过输入 1 或 2 作为输入来选择一个。如果用户输入错误,他将被要求重新输入它的选择。

#include <stdio.h>

char c;

int main() {
    printf("What do you wish to do ?\nEnter 1 to convert raw PCM to WAV \nEnter 2 to convert WAV to raw PCM \nChoice : ");
    c = fgetc(stdin);
    while(c != '1' && c != '2') {
        printf("You specified an incorrect input\nEnter 1 to convert raw PCM to WAV\nEnter 2 to convert WAV to raw PCM\nChoice : ");
        c = fgetc(stdin);
    return 0;
}

我通过输入 78 作为输入来测试这种“输入不正确”的情况,但这里是控制台输出:

What do you wish to do ?
Enter 1 to convert WAV to raw PCM
Enter 2 to convert raw PCM to WAV
Choice : 78
You specified an incorrect input
Enter 1 to convert raw PCM to WAV
Enter 2 to convert WAV to raw PCM
Choice : You specified an incorrect input
Enter 1 to convert raw PCM to WAV
Enter 2 to convert WAV to raw PCM
Choice : You specified an incorrect input
Enter 1 to convert raw PCM to WAV
Enter 2 to convert WAV to raw PCM
Choice :

在要求进一步输入之前,它连续三次显示“输入错误”消息。 重复的原因可能是什么?
注意:如果我使用 getchar() 而不是 fgetc(stdin),也会发生同样的事情。

输入 78<Enter> 作为三个单独的字符 '7''8''\n' 添加到输入中。这就是为什么您三次收到无效输入消息的原因。

我的建议是停止使用字符,而是将整行作为单个字符串读取,然后尝试将其解析为整数。也许像

// Input validation loop
for (;;)
{
    // Print prompt
    printf("What do you wish to do ?\nEnter 1 to convert raw PCM to WAV \nEnter 2 to convert WAV to raw PCM \nChoice : ");

    // Read the whole next line as input
    char input[256];
    if (fgets(input, sizeof input, stdin) == NULL)
    {
        // TODO: Input error, handle it accordingly
        exit(EXIT_FAILURE);
    }

    // Parse the input
    unsigned choice;
    if (sscanf(input, "%u", &choice) != 1)
    {
        printf("Input was not a number\n");
        continue;
    }

    // See if the input was valid
    if (choice != 1 && choice != 2)
    {
        printf("Input was not a valid choice, please try again\n");
        continue;
    }

    // By this point the input and its validation was successful,
    // don't loop anymore
    break;
}