Search code examples
cinputstdinfgetc

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


I'm writing a program that has 2 functionnalities. When he opens the program, the user is asked to choose one by entering either 1 or 2 as an input. If the user enters something wrong, he will be asked to enter its choice again.

#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;
}

I tested this "incorrect input" case by entering 78 as the input, but here is the console output :

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 :

It displays the "incorrect input" message three times in a row before asking for further input. What could be the cause of this repetition ?
Note : the same thing happens if I use getchar() instead of fgetc(stdin).


Solution

  • The input 78<Enter> is added to the input as the three separate characters '7', '8' and '\n'. That's why you get the invalid input message thrice.

    My suggestion is that you stop using characters, and instead read the whole line as a single string, and then attempt to parse it as an integer instead. Perhaps something like

    // 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;
    }