Search code examples
ciodo-whilegetchar

C - Do While adding extra Step


When I run the code below, it executes correctly but adds an extra iteration before I can input again. Not sure why. I am going to be using it for fork and pipe parent process to children. That step will come after the user inputs # of processes.

Code:

#include <stdio.h> 

int main(void) {
    int num_processes;
    int running = 1;
    do {
        printf ("How many processes do you want? (1, 2 or 4) \n");
        num_processes = getchar();
        num_processes -= '0';

        if(num_processes == 1 || num_processes == 2 || num_processes == 4){
            int temp = num_processes - 1;
            printf("\n1 Parent and %d child processes\n", temp);
            printf("----------------------------------\n");
            running = 0;
        } else {
            printf("Invalid Input, please try again.\n");
        }
    } while(running == 1);

    // Do important stuff

    return(0);
}

Out:

How many processes do you want? (1, 2 or 4)
3
Invalid Input, please try again.
How many processes do you want? (1, 2 or 4)
Invalid Input, please try again.
How many processes do you want? (1, 2 or 4)
2

1 Parent and 1 child processes
----------------------------------

Solution

  • Think what happens when you give your first input. You type 3, and then you hit Enter.

    Now, in the Standard input buffer, there are two items awaiting to be consumed, 3 and \n (which is Enter).

    You enter the body of the loop for the very first time, 3 is consumed. Now next in line awaits the \n...

    When you enter the loop's body again (for the second time), the next character to be read by the Standard input buffer is \n, and that's what the second getchar() happily returns to you.

    Here is a quick fix:

    do {
        printf ("How many processes do you want? (1, 2 or 4) \n");
        // Eat trailing newline character, if any
        do {
          num_processes = getchar();      // read a character
        } while(num_processes == '\n');   // if it was the newline character, repeat
                                          // until `num_processes` is not the newline character
    
        // Continue with your logic..
        num_processes -= '0';
    

    Output:

    How many processes do you want? (1, 2 or 4) 
    3
    Invalid Input, please try again.
    How many processes do you want? (1, 2 or 4) 
    2
    
    1 Parent and 1 child processes
    ----------------------------------
    

    PS: As @Barmar commented, if you want to read lines, then use fgets(). Read more here: How to use fgets() to control the execution of while loop through user input in c?