Search code examples
cbufferfflush

Issue clearing input stream in C


I've recently started learning C, and while trying to make a simple calculator, I encountered an issue while trying to clear the input stream. I tried using fflush(stdin); but apparently, it didn't do anything.

Operating System: macOS Sierra (Version 10.12.5 (16F73))

Apple LLVM version 8.1.0 (clang-802.0.42)

Editor Used: Sublime Text 3

Here is my code:

#include <stdio.h>

int main()
{
    int num1, num2;
    char opr;
    char choice = 'y';

    while (choice == 'y') {
        printf("Enter numbers separated with a comma: \n");
        scanf("%d, %d", &num1, &num2);

        printf("Enter an operator: \n");
        fflush (stdin);
        scanf("%c", &opr);

        switch (opr) {
            case '+':
                printf("The sum is %ld\n", (long int) num1 + num2);
                break;
            case '-':
                printf("The difference is %ld\n", (long int) num1 - num2);
                break;
            case '*':
                printf("The product is %ld\n", (long int) num1 * num2);
                break;
            case '/':
                printf("The quotient is %ld and the remainder is %ld\n",
                    (long int) num1 / num2, (long int) num1 % num2);
                break;
            default:
                printf("You've entered an undefined operator\n");
                printf("Please enter + - * or /\n");
                break;
        }

        printf("Do you want to repeat? (y/n):  \n");
        fflush(stdin);
        scanf("%c", &choice);
    }

    return 0;
}

Here is the terminal output:

$ ./calculator_basic
Enter numbers separated with a comma:
20, 30
Enter an operator:
You've entered an undefined operator
Please enter + - * or /
Do you want to repeat? (y/n):
n

An easy solution that I found out was to simply interchange the places of

printf("Enter numbers separated with a comma: \n");<br>
scanf("%d, %d", &num1, &num2);

and

printf("Enter an operator: \n");
fflush (stdin);
scanf("%c", &opr);

I understand that the problem is due to the enter key being stored in the input buffer after entering the numbers in scanf("%d, %d", &num1, &num2); and scanf("%c", &opr); then uses this stored enter key (in the buffer) as its input which creates the problem (ie: none of the cases in switch defined by me work and the default case runs, all this without even me being able to enter an operator)

I tried using fflush(stdin); before getting new character inputs but it doesn't seem to work.

The thing is that fflush(stdin); is working when I'm trying to run this code in a Windows system, but it's not working on macOS regardless of the editor I'm using (tried both Sublime Text 3 and Visual Studio Code)

Can anyone help me out regarding why fflush(stdin); might not be working. Also I've read about it on the internet and one solution was to use cin.get(); instead of getchar();. I tried it but this didn't work as well. I don't want to interchange those two pieces of codes (mentioned above) because that would be hit and trial. I want to run the code in the same order (entering the numbers first and then the operator)

Also, I know questions on fflush(stdin) have been asked previously, but I've read the answers and can't seem to figure out anything that works for me.


Solution

  • Newline character

    To remove the (only) newline character ('\n') left in buffer, introduce a space (' ') in the format string of scanf(). This directive matches with any no of white spaces (even zero).

    scanf(" %c", &opr);
    

    or you could just use getchar() to read '\n' whenever needed, thus leaving the buffer with no characters.

    Now the code will work properly as long as you enter the input correctly.

    If there's more than a single character left in the buffer (for any reason), use the following code to flush i/p stream.


    Flushing stdin

    To flush the input stream try one of the following ways.

        scanf("%*[^\n]");
        getchar();
    

    or

        int ch;
        while((ch = getchar()) != '\n' && ch != EOF);
    

    use it only when you are certain that the buffer isn't empty otherwise in either case the code expects/prompts for an input.


    scanf()

     scanf("%d, %d", &num1, &num2);
    

    Unless you wrote it intentionally ',' and space (' ') are redundant. If that's the case scanf() expects two integers to be seperated by a comma and a possible whitespace(s).