Loop skips over getchar in C?

124 views Asked by At

I am working on a simple program in C that asks the user to give an input in a loop until they enter the letter Q when prompted. When I run the program however, it immediately skips the prompt to enter a character and asks the user to enter another input. Any idea why this happens and how I can fix it?

Here is my code:

    while (exit != 'q' && exit != 'Q') {
        printf("Please enter the grade for assignment #%d: ", assignmentNumber);
        scanf("%lf", &gradeInput);

        printf("Press q to quit, press any other character to continue: ");
        exit = getchar();
    } 

I tried changing the getchar to scanf(%c%*c) like I saw someone suggest under a post with a similar problem. It did make it so the prompt to enter a character actually worked, but the loop no longer ended when Q is entered.

3

There are 3 answers

7
Jibel On

It looks like the issue you're facing is related to the way the newline character left in the input buffer after reading a double (with scanf("%lf", &gradeInput)) is affecting the behaviour of getchar(). The getchar() function reads the next character from the input buffer, which includes any leftover newline characters.

To fix this issue, you can clear the input buffer after reading the grade by consuming the newline character. Here's an updated version of your code:

#include <stdio.h>

int main() {
    char exit = ' ';
    double gradeInput;
    int assignmentNumber = 1;

    do {
        printf("Please enter the grade for assignment #%d: ", assignmentNumber);

        if (scanf("%lf", &gradeInput) != 1) {
            printf("Invalid input. Please enter a valid number.\n");
            while (getchar() != '\n'); // Clear the input buffer
            continue;
        }

        while ((exit = getchar()) != '\n' && exit != EOF); // Clear the input buffer

        printf("Press q to quit, press any other character to continue: ");
        exit = getchar();
        while (getchar() != '\n'); // Clear the input buffer

        assignmentNumber++;
    } while (exit != 'q' && exit != 'Q');

    return 0;
}

In this code, we use a while loop to clear the input buffer by reading characters until a newline character is encountered. This ensures that any leftover characters, including the newline character, are removed from the input buffer before attempting to read the exit character. This should fix the issue and allow your loop to end when Q or q is entered.

0
Vlad from Moscow On

This call of getchar

exit = getchar ();

can read new line character '\n'.

Instead change the statement like

scanf( " %c", &exit );
        ^^^

provided that exit has the type char.

Pay attention to the leading space in the format string. It allowes to skip white space characters.

Also it would be better to change the while loop to do-while loop like

do 
{
    printf("Please enter the grade for assignment #%d: ", assignmentNumber);
    scanf("%lf", &gradeInput);

    printf("Press q to quit, press any other character to continue: ");
    scanf( " %c", &exit );
} while ( exit != 'q' && exit != 'Q' );
0
chqrlie On

The problem is getchar() reads the next character from the input line after the floating point number typed by the user. This could be anything, but in most cases, this character will be the newline stored into the input stream when the user hit the Enter key.

You should modify your program to:

  • read input one line at a time
  • check for end of file
  • check for success in the conversion of the user input as a number

Here is a modified version:

#include <stdio.h>

int main() {
    double gradeInput;
    int assignmentNumber = 1;

    for (;;) {
        char input[128];
        printf("Please enter the grade for assignment #%d: ", assignmentNumber);
        if (!fgets(input, sizeof input, stdin)) {
            /* end of file */
            break;
        }
        if (sscanf(input, "%lf", &gradeInput) != 1) {
            printf("invalid input: %s\n", input);
            continue;
        }
        /* handle the grade */
        // [...]
        assignmentNumber++;

        printf("Press q to quit, press any other character to continue: ");
        if (!fgets(input, sizeof input, stdin)) {
            /* end of file */
            break;
        }
        if (input[0] == 'q' || input[0] == 'Q')
            break;
    }
    return 0;
}