0

This is the code which I'm trying to run on my Mac. In this the statement after fflush doesn't work. After fflush the compiler should stop and wait for the user input but it doesn't.

Can anyone tell me why this is happening or is there any other way to do it?

int main()
{
    int pos,neg,zero,num;
    char ans = 'y';

    pos=neg=zero=0;
    while(ans == 'y' || ans=='Y')
    {
        printf("\nEnter a number : ");
        scanf("%d",&num);

        if(num==0)
            zero++;

        if(num>0)
            pos++;

        if(num<0)
            neg++;

        fflush(stdin);
        printf("\nDo you want to continue?\n\n");
        scanf("%c",&ans);    
    } 
    printf("You entered %d positive numbers\n",pos);
    printf("You entered %d negative numbers\n",neg);
    printf("You entered %d zeros \n",zero);

    return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Smriti Sethi
  • 45
  • 1
  • 12
  • 2
    `fflush(stdin)` is undefined behaviour. read that many times here, so it must be true :) – Jean-François Fabre Jan 05 '18 at 20:28
  • 1
    @Jean-FrançoisFabre `fflush(stdin)` *is* undefined behavior according to the C standard. However, both POSIX and Windows define the behavior. Unfortunately, in both specifications the defined behavior is absolutely useless. – EOF Jan 05 '18 at 20:30

1 Answers1

2

From standard 7.21.5.2

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

You were having undefined behavior in your code. More clearly, fflush won't work. The most common way to do it would be something as shown below:

int c;
while ((c = getchar()) != '\n' && c != EOF){}

Another solution would be to use (much easier for you but not robust)

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

This will make sure all white space is being consumed. This will solve one of the problem that may arise, but not all. (The others arise due to use of scanf and wrong input).

Side note

Also another way to get rid of this problem altogether would be to use fgets or similar to read one line and then use strtol or strtod to get the desired input parsed from the inputted line. scanf is extremely useful for formatted input. The scenario which you will have - it is better to use fgets, there are too many cases with scanf that you have to deal with otherwise.

For wrong input you need to flush the standard input so that you don't have to deal with them again in the next scanf. If you use fgets then you will get the input line from the stdin and then if you can parse it and the input is correct - you go on processing it, else you discard the whole line and wait for the next fgets call.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
user2736738
  • 30,591
  • 5
  • 42
  • 56