Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between fflush(stdin) and flushstdin()

Tags:

c

stdin

fflush

What is the difference between using fflush(stdin) and flushstdin()? The only difference I know is that I need to write that void stuff before using flushstdin(), but I don't know why.

void flushstdin()
{
    int c;
    while((c = getchar()) != '\n' && c != EOF); 
}
int main () {
    float a, b, c;
    float s=0, ar1=0, ar2=0;
    printf("Inform value of side A");
    while(scanf("%f",&a) != 1 || a <= 0){ 
        printf("Invalid value.\n");
        flushstdin();
    }
}

and

int main(){
    float a,b,c,s=0;
    printf("Inform value of side A.");
    while(scanf("%f",&a) != 1 || a<=0){
        printf("Invalid value.\n");
        fflush(stdin);
    }
}

I'm a beginner! Which code is the best? Or they are equal?

like image 586
Rafael Moura Avatar asked Dec 19 '22 03:12

Rafael Moura


2 Answers

Difference is that flushstdin is user defined and the only way in standard C to flush stdin.
fflush is a standard library function. fflush(stdin); will invoke undefined behavior.

c- faq: 12.26a:

fflush is defined only for output streams. Since its definition of "flush" is to complete the writing of buffered characters (not to discard them), discarding unread input would not be an analogous meaning for fflush on input streams.

c-faq: 12.26b:

There is no standard way to discard unread characters from a stdio input stream. Some vendors do implement fflush so that fflush(stdin) discards unread characters, although portable programs cannot depend on this. (Some versions of the stdio library implement fpurge or fabort calls which do the same thing, but these aren't standard, either.) Note, too, that flushing stdio input buffers is not necessarily sufficient: unread characters can also accumulate in other, OS-level input buffers. If you're trying to actively discard input (perhaps in anticipation of issuing an unexpected prompt to confirm a destructive action, for which an accidentally-typed "y" could be disastrous), you'll have to use a system-specific technique to detect the presence of typed-ahead input; see questions 19.1 and 19.2. Keep in mind that users can become frustrated if you discard input that happened to be typed too quickly.

like image 198
haccks Avatar answered Jan 05 '23 19:01

haccks


They are quite different. They can both "flush" input, but in different senses of that word.

fflush is a standard C function. Its behavior on input streams such as stdin is undefined -- meaning that the C standard does not define its behavior.

Some systems do define the behavior of fflush on an input stream. For example on Linux:

For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.

You can rely on fflush(stdin) to behave in accordance with this description if your program runs on a Linux-based system, or on another system that documents the same behavior. Your program's behavior will not be portable; on other systems, it might behave in arbitrarily bad ways. (Most likely if fflush(stdin) doesn't work, it will do nothing other than returning an error indication, but that's not guaranteed.)

Your own flushstdin function does something different from the Linux behavior of fflush(stdin). It reads and discards all input functions up to the first newline or until EOF (which is triggered either by end-of-file or by an error). It does this regardless of whether that input is buffered or not.

For example, suppose you type the chacters hello (without a newline), then your program calls fflush(stdin), and then you enter a newline.

fflush(stdin), given the Linux documented behavior, will discard the hello and return immediately, leaving the newline to be read by a later call. It "flushes" stdin in the sense that it discards all pending input, regardless of what it is.

Your flushstdin() function will read and discard the hello and then wait until you type Enter (or Ctrl-D), and then read and discard that. It reads and discards all input up to a newline or EOF, regardless of whether it was pending at the time of the call.

And again, the behavior of fflush(stdin) is not defined by the C standard, so using it makes your program non-portable (and your compiler will not necessarily warn you about that).

Incidentally, "that void stuff" is the definition of the flushstdin function. It's not needed for fflush because that's a standard C library function that's already defined for you.

like image 33
Keith Thompson Avatar answered Jan 05 '23 18:01

Keith Thompson