How do I fix buffer errors in while?

When you run this code, it somehow works as well as the number of characters entered by scanf after the first operation.
What’s the problem?

I filled in the blank space before %c because I thought it might be a buffer problem, but the error still occurs.

void EX18() {
    float x, y;
    char op;
    int i = 0;
    while (1) {
        /*
        printf("\n******************** \n");
        printf("A ---- Add \n");
        printf("S ---- Subtract \n");
        printf("M ---- Multiply \n");
        printf("D ---- Divide \n");
        printf("Q ---- Quit \n");
        printf("******************** \n");
        */
        i++;
        printf("\n%dth iteration \n",i);
        printf("Select an operation: ");
        scanf(" %c", &op);

        if (op == 'Q') break;
        else {
            switch (op) {
            case 'A':
                printf("Enter two numbers separated by a space: ");
                scanf("%f %f", &x, &y);
                printf("%.2f \n", x + y);
                break;
            case 'S':
                printf("Enter two numbers separated by a space: ");
                scanf("%f %f", &x, &y);

                printf("%.2f \n", x - y);
                break;
            case 'M':
                printf("Enter two numbers separated by a space: ");
                scanf("%f %f", &x, &y);

                printf("%.2f \n", x * y);
                break;
            case 'D':
                printf("Enter two numbers separated by a space: ");
                scanf("%f %f", &x, &y);

                printf("%.2f \n", x / y);
                break;
            default:
                printf("\nUnknown command. Please try again.\n");
            }
        }
    }
}

int main()
{
    EX18();
    //TEST5();
    return 0;
}

Result Screen :

1th iteration
Select an operation: 00

Unknown command. Please try again.

2th iteration
Select an operation:
Unknown command. Please try again.

3th iteration
Select an operation: 000

Unknown command. Please try again.

4th iteration
Select an operation:
Unknown command. Please try again.

5th iteration
Select an operation:
Unknown command. Please try again.

6th iteration
Select an operation:

>Solution :

The problem is that you read the "command" character by character. If you input two invalid characters the first scanf(" %c", &op) call will read the first, but the second invalid input is still in the buffer to be read by the next call.

As I advised in a comment, use fgets to read whole lines, and then e.g. sscanf to parse the input:

char buffer[256];  // No need to skimp on space

if (!fgets(buffer, sizeof buffer, stdin))
{
    // Failed to read input
    // TODO: Handle this case
}

if (sscanf(" %c", &op) != 1)
{
    // Invalid input
    // TODO: Handle this case
}

It’s more code, but it will be more robust and safer than your current code.

Do something similar for the numeric input.

I also suggest you put these in separate functions, which makes it easier to read the code, to test it and to debug it when needed.


Please note that while the code describe above will make your input handling better and safer, it’s not perfect.

An obnoxious user could input a line longer than 255 characters, in which case we’re basically back where we started, where you get left over input in the buffers.

To be really safe from it you should check if the last character in the input from fgets is a newline, and if not then tell the user about the invalid input and use fgets (of perhaps even just fgetc) in a loop until you have read the newline.

Leave a Reply