11

I used the fflush() in Linux GCC but it did not work. Are there any alternatives for that function? Here is my code:

#include<stdio.h>
void main()
{
  char ch='y';
  while(ch=='y')
  {
    int a;
    printf("Enter some value:");
    scanf("%d",&a);
    fflush(stdin);
    printf("Do you want to continue?");
    scanf("%c",&ch)
  }

The output that I got is:

Enter some value: 10

Then the program ends. That's all. What can I do in Linux? Is there an alternative function?

Lundin
  • 195,001
  • 40
  • 254
  • 396
sundar
  • 396
  • 1
  • 6
  • 19

9 Answers9

21

Don't use fflush, use this function instead:

#include <stdio.h>
void clean_stdin(void)
{
    int c;
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);
}

fflush(stdin) depends of the implementation, but this function always works. In C, it is considered bad practice to use fflush(stdin).

Mathuin
  • 790
  • 1
  • 6
  • 13
  • 6
    `fflush(stdin)` is a bad practice, not `fflush`. ;) – md5 Jul 03 '13 at 18:26
  • @md5 what do you mean "not fflush". do you mean fflush is good practice? or fflush with no parameters doesn't exist? – barlop Dec 19 '15 at 16:09
  • 1
    @barlop: `fflush` might be useful, e.g. with an output stream: `fflush(stdout)` forces the output to be written (see http://paste.awesom.eu/4dym). Here it is _not_ an undefined behavior. – md5 Dec 19 '15 at 17:04
  • 3
    Can you explain how this works instead of just saying "dont use that, use this, it works"? – NOP da CALL Feb 16 '18 at 05:47
  • 1
    While this will work if the buffer has some input. If it will be empty getchar() will force the console to ask for additional input meaning you will need to click additional "enter" key to create a newline. Maybe fflush(stdin) is a bad practice, but it prevents this problem – Denis_LT Sep 28 '21 at 11:27
7

One that always works on Linux:

#include <termios.h>
#include <unistd.h>

void clean_stdin()
{
        int stdin_copy = dup(STDIN_FILENO);
        /* remove garbage from stdin */
        tcdrain(stdin_copy);
        tcflush(stdin_copy, TCIFLUSH);
        close(stdin_copy);
}

You can use tcdrain and tcflush not only for in/out/err fd.

ataraxic
  • 2,157
  • 2
  • 17
  • 10
5

The behavior of fflush is not defined for input streams (online 2011 standard):

7.21.5.2 The fflush function

Synopsis

1

    #include <stdio.h>
    int fflush(FILE *stream);
Description

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.

3 If stream is a null pointer, the fflush function performs this flushing action on all streams for which the behavior is defined above.

Returns

4 The fflush function sets the error indicator for the stream and returns EOF if a write error occurs, otherwise it returns zero.
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • `fflush` on input streams is not defined in POSIX.1-2001, but **it is** defined in POSIX.1-2008 – iBug Apr 17 '19 at 14:51
2

I faced the same problem while working on LINUX and an alternative solution of this problem can be that you define a dummy character lets say char dummy; and put a scanf() to scan it just before your actual input takes place. This worked for me. I hope it would work for you too.

Nikhil Wagh
  • 1,376
  • 1
  • 24
  • 44
1

fflush() doesn't do much for input streams but since scanf() never returns this doesn't matter. scanf() blocks because the terminal window doesn't send anything to the C program until you press Enter

You have two options:

  1. Type 10 Enter
  2. Put the terminal into raw mode.

The second option has many drawbacls like you will lose editing capabilities, so I suggest to read the input line by line.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
1

You must include and use __fpurge(whatever you want) instead.

Salute from argentina

0

Use getchar() instead, after scanf

0
#include<stdio.h>
int main()
{
char ans='y';
int a;
while(ans=='y'||ans=='Y')
    {

     printf("Type a number:-");
     scanf("%d",&a);
     printf("square of number = %d\nwant to enter 
     number again(y/n)?\nANS=",a*a); 
     scanf("%s",&ans);//use %s in place of %c
     }
return 0;
}
-1

By using bzero(); system call in Linux we can flush the previous stored value.
Please read the manual page of bzero(); by typing in terminal man bzero. try this example

#include<stdio.h>
#include<string.h>

int main()
{
  char buf[]={'y'};
  int num;
  while(buf[0]=='y')
  {
    printf("enter number");
    scanf("%d",&num);
    printf("square of %d is %d\n",num,num*num);
    bzero(buf, 1);
    printf("want to enter y/n");
    scanf("%s",&buf[0]);
  }
  return 0;
} 
Tomer Cohen
  • 374
  • 6
  • 13
Raj Ravi
  • 7
  • 2
  • This code will cause a buffer overflow on the `scanf("%s"` line. Also, `buf[0] = 0;` would be less error-prone than `bzero(buf, 1)`. – M.M Feb 11 '17 at 04:34