The answer to this is that fflush(stream) is only formally defined for output streams, so fflush(stdout) is OK, but fflush(stdin) is not.

The purpose of fflush(stream) is to make the operating system flush any buffers to the underlying file. For an example of a legitimate use, students often have problems like “my prompt doesn't appear!” if they do something like:

printf("Enter a number: ");

However, they find that this works just fine:

printf("Enter a number:\n");

Of course, they don't want a newline after their prompt, so they have a bit of a problem.

The reason for this is that the output to stdout is buffered by the OS and the default behavior is (often) only to actually write the output to the terminal when a newline is encountered. Adding an fflush(stdout) after the printf() solves the problem:

printf("Enter a number: ");
fflush(stdout);

Now, working by analogy, people often think that fflush(stdin) should discard any unused input, but if you think about it a little bit that doesn't make much sense. What does it mean to “flush” an input buffer? Where is it “flushed” to? If you flush an output buffer, the output is sent to the underlying file or the terminal, where it would eventually wind up anyway, but where would input “eventually end up anyway”? There's no way of knowing! What should the behavior be if the input stream data comes from a file or a pipe or a socket? It isn't at all clear for input streams what the behavior of fflush() should be, but it's very clear for output streams in all cases. Hence, fflush() is only defined for output streams.

The reason why the erroneous use of fflush(stdin) became commonplace is that, many years ago, a few operating systems did implement a scheme where it worked as many people expected, discarding unused input. Microsoft DOS is a good example. Surprisingly, modern versions of Linux also implement fflush() for input streams.

The right thing to do with “extra” unwanted terminal input is simply to read it and do nothing with it. This is almost as easy as calling fflush(stdin), works everywhere, and doesn't rely on formally undefined behavior.

The C standard says:

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.

POSIX says (also explicitly defers to C standard):

If stream points to an output stream or an update stream in which the most recent operation was not input, fflush() shall cause any unwritten data for that stream to be written to the file, ...

But the Linux manpage says:

For output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function. For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application. The open status of the stream is unaffected.

Answer from Emmet on Stack Overflow
Top answer
1 of 2
47

The answer to this is that fflush(stream) is only formally defined for output streams, so fflush(stdout) is OK, but fflush(stdin) is not.

The purpose of fflush(stream) is to make the operating system flush any buffers to the underlying file. For an example of a legitimate use, students often have problems like “my prompt doesn't appear!” if they do something like:

printf("Enter a number: ");

However, they find that this works just fine:

printf("Enter a number:\n");

Of course, they don't want a newline after their prompt, so they have a bit of a problem.

The reason for this is that the output to stdout is buffered by the OS and the default behavior is (often) only to actually write the output to the terminal when a newline is encountered. Adding an fflush(stdout) after the printf() solves the problem:

printf("Enter a number: ");
fflush(stdout);

Now, working by analogy, people often think that fflush(stdin) should discard any unused input, but if you think about it a little bit that doesn't make much sense. What does it mean to “flush” an input buffer? Where is it “flushed” to? If you flush an output buffer, the output is sent to the underlying file or the terminal, where it would eventually wind up anyway, but where would input “eventually end up anyway”? There's no way of knowing! What should the behavior be if the input stream data comes from a file or a pipe or a socket? It isn't at all clear for input streams what the behavior of fflush() should be, but it's very clear for output streams in all cases. Hence, fflush() is only defined for output streams.

The reason why the erroneous use of fflush(stdin) became commonplace is that, many years ago, a few operating systems did implement a scheme where it worked as many people expected, discarding unused input. Microsoft DOS is a good example. Surprisingly, modern versions of Linux also implement fflush() for input streams.

The right thing to do with “extra” unwanted terminal input is simply to read it and do nothing with it. This is almost as easy as calling fflush(stdin), works everywhere, and doesn't rely on formally undefined behavior.

The C standard says:

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.

POSIX says (also explicitly defers to C standard):

If stream points to an output stream or an update stream in which the most recent operation was not input, fflush() shall cause any unwritten data for that stream to be written to the file, ...

But the Linux manpage says:

For output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function. For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application. The open status of the stream is unaffected.

2 of 2
20

fflush(stdin) invokes undefined behaviour.

fflush() is defined only for output streams. You should not do it.


On Unix, Ctrl-Z sends a TSTP signal (SIGTSTP) which by default causes the process to suspend execution.

🌐
GeeksforGeeks
geeksforgeeks.org › c language › use-fflushstdin-c
Use of fflush(stdin) in C - GeeksforGeeks
September 15, 2023 - Although using “fflush(stdin)” after “scanf()” statement also clears the input buffer in certain compilers, it is not recommended to use it as it is undefined behavior by the language standards.
Discussions

What is the use of fflush(stdin) in c programming? - Stack Overflow
The man page is actually a bit misleading: it describes the (POSIX-mandated, not just Linux-specific) behavior for seekable input streams. The Linux fflush does exactly nothing when called on stdin (well, it attempts an lseek, catches ESPIPE, and then does exactly nothing) 2015-03-17T02:40... More on stackoverflow.com
🌐 stackoverflow.com
c - What is the exact meaning of "fflush(stdin)" in the following program? - Stack Overflow
You're claiming that fflush(stdin) has a certain behavior. However the standard does not define the behavior of fflush on input streams, so it is in fact undefined behavior. Note that fflush(stdin) will simply not do anything at all on many platforms, so your example won't do what you claim ... More on stackoverflow.com
🌐 stackoverflow.com
c - Using fflush(stdin) - Stack Overflow
In 2021, zwol commented that the Linux documentation has been improved. It seems to me that there is still room for improvement. In 2015, I was a bit puzzled and surprised at the Linux documentation saying that fflush(stdin) will work. Despite that suggestion, it most usually does not work on Linux. More on stackoverflow.com
🌐 stackoverflow.com
What does fflush(stdin) do? - Post.Byes
hi, what is the use of fflush(stdin) in c programing. regards, santosh More on post.bytes.com
🌐 post.bytes.com
🌐
Reddit
reddit.com › r/learnprogramming › [c] can someone please explain fflush(stdin) to me?
r/learnprogramming on Reddit: [C] Can someone please explain fflush(stdin) to me?
July 1, 2015 -

I understand that this command flushes out the input stream but what does it mean by "flushing the stream".

🌐
TutorialsPoint
tutorialspoint.com › use-of-fflush-stdin-in-c
Use of fflush(stdin) in C
June 24, 2020 - The function fflush(stdin) is used to flush the output buffer of the stream. It returns zero, if successful otherwise, returns EOF and feof error indicator is set. Here is the syntax of fflush(stdin) in C language,
🌐
Scaler
scaler.com › home › topics › fflush() in c
fflush() in C - Scaler Topics
May 4, 2023 - The function fflush(stdin) is used to flush the output buffer of the stream. It returns zero, if successful otherwise, returns EOF and of error, the indicator is set.
🌐
Quora
quora.com › Why-is-fflush-stdin-used-in-C
Why is fflush (stdin) used in C? - Quora
Answer (1 of 7): Contrary to popular belief, calling the fflush function on an input stream leads to undefined behavior. If you look at the C standard, you’ll find the following: > “If stream [the argument] points to an output stream or an update stream in which the most recent operation was n...
Find elsewhere
🌐
Quora
quora.com › Why-do-we-use-the-functions-fflush-stdin-and-fflush-stdout-in-c
Why do we use the functions fflush(stdin) and fflush(stdout) in c? - Quora
Answer (1 of 6): Let us first understand the different I/O functions that the standard library provides and their relationship to each other. Output For formatted output, you have fprintf / printf / and their variants. For string output, you have fputs. For output of uninterpreted data i.e. raw ...
🌐
Quora
quora.com › What-is-fflush-stdin-in-a-C-language
What is fflush (stdin); in a C language? - Quora
Answer (1 of 14): Undefined behavior. I have read most of the answers for this question, and they all say its to clear the input stream. To them I say, start reading the C standard before giving out such answers. Though [code ]fflush()[/code] function is used to clear a stream, using it on [cod...
🌐
Linux Hint
linuxhint.com › fflush-stdin-in-c-programming
What Does fflush(stdin) Do in C Programming – Linux Hint
The fflush(stdin) function is used with input operations to ensure that data is properly processed, and nothing is left behind in the input buffer. In C programming, every input operation will leave some data behind in the input buffer. This data is left there until the program chooses to process ...
🌐
TutorialsPoint
tutorialspoint.com › c_standard_library › c_function_fflush.htm
C Library - fflush() function
The C library fflush() function flushes the output buffer of a stream.This function forces a write of all buffered data for the given output or update stream to the file. When applied to an input stream, its behavior is undefined.
🌐
Sololearn
sololearn.com › en › Discuss › 570915 › what-is-the-use-of-fflushstdin-in-c-programmingi-know-here-c-is-not-included
What is the use of fflush(stdin) in c programming(i know here c is not included) | Sololearn: Learn to code for FREE!
When you use a program and give ... them , they stay there and if you want to delete them from there, you can use fflush(stdin) function which clear the box the same way your toilet does when you flush it......
🌐
IncludeHelp
includehelp.com › c-programs › fflush-function-in-c-language-with-example.aspx
fflush() function in C language with Example
#include <stdio.h> #include <stdlib.h> int main() { //Initialize the file pointer FILE* f; //Take a array of characters char ch[100]; //Create the file for write operation f = fopen("includehelp.txt", "w"); printf("Enter five strings\n"); for (int i = 0; i < 4; i++) { //take the strings from the users scanf("%[^\n]", &ch); //write back to the file fputs(ch, f); //every time take a new line for the new entry string fputs("\n", f); //except for last entry.Otherwise print the last line twice //clear the stdin stream buffer //fflush(stdin); //if we don't write this then after taking string //%[^\n
Top answer
1 of 7
95

Simple: this is undefined behavior, since fflush is meant to be called on an output stream. This is an excerpt from the C standard:

int fflush(FILE *ostream);

ostream 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.

So it's not a question of "how bad" this is. fflush(stdin) is simply not portable, so you should not use it if you want your code to be portable between compilers.

2 of 7
54

Converting comments into an answer.

TL;DR — Portable code doesn't use fflush(stdin)

The rest of this answer explains why portable code does not use fflush(stdin). It is tempting to add "reliable code doesn't use fflush(stdin)", which is also generally true.

Standard C and POSIX leave fflush(stdin) as undefined behaviour

The POSIX, C and C++ standards for fflush() explicitly state that the behaviour is undefined (because stdin is an input stream), but none of them prevent a system from defining it.

ISO/IEC 9899:2011 — the C11 Standard — says:

§7.21.5.2 The fflush function

¶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.

POSIX mostly defers to the C standard but it does mark this text as a C extension.

[CX] ⌦ For a stream open for reading, if the file is not already at EOF, and the file is one capable of seeking, the file offset of the underlying open file description shall be set to the file position of the stream, and any characters pushed back onto the stream by ungetc() or ungetwc() that have not subsequently been read from the stream shall be discarded (without further changing the file offset). ⌫

Note that terminals are not capable of seeking; neither are pipes or sockets.

Microsoft defines the behaviour of fflush(stdin) as a no-op

In 2015, Microsoft and the Visual Studio runtime used to define the behaviour of fflush() on an input stream like this (but the link leads to different text in 2021 — and even the text in the '2015' version is different):

If the stream is open for input, fflush clears the contents of the buffer.

M.M notes:

Cygwin is an example of a fairly common platform on which fflush(stdin) does not clear the input.

This is why this answer version of my comment notes 'Microsoft and the Visual Studio runtime' — if you use a non-Microsoft C runtime library, the behaviour you see depends on that library.

Weather Vane pointed out to me in a comment to another question that, at some time before June 2021, Microsoft changed its description of fflush() compared with what was originally specified when this answer was written in 2015. It now says:

If the stream was opened in read mode, or if the stream has no buffer, the call to fflush has no effect, and any buffer is retained. A call to fflush negates the effect of any prior call to ungetc for the stream.

Caveat Lector: it is probably best not to rely on fflush(stdin) on any platform.

Linux documentation and practice seem to contradict each other

Surprisingly, Linux nominally documents the behaviour of fflush(stdin) too, and even defines it the same way (miracle of miracles). This quote is from 2015.

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

In 2021, the quote changes to:

For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application. The open status of the stream is unaffected.

And another source for fflush(3) on Linux agrees (give or take paragraph breaks):

For input streams associated with seekable files (e.g., disk files, but not pipes or terminals), fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.

Neither of these explicitly addresses the points made by the POSIX specification about ungetc().

In 2021, zwol commented that the Linux documentation has been improved. It seems to me that there is still room for improvement.

In 2015, I was a bit puzzled and surprised at the Linux documentation saying that fflush(stdin) will work. Despite that suggestion, it most usually does not work on Linux. I just checked the documentation on Ubuntu 14.04 LTS; it says what is quoted above, but empirically, it does not work — at least when the input stream is a non-seekable device such as a terminal.

demo-fflush.c

#include <stdio.h>

int main(void)
{
    int c;
    if ((c = getchar()) != EOF)
    {
        printf("Got %c; enter some new data\n", c);
        fflush(stdin);
    }
    if ((c = getchar()) != EOF)
        printf("Got %c\n", c);

    return 0;
}

Example output

$ ./demo-fflush
Alliteration
Got A; enter some new data
Got l
$

This output was obtained on both Ubuntu 14.04 LTS and Mac OS X 10.11.2. To my understanding, it contradicts what the Linux manual says. If the fflush(stdin) operation worked, I would have to type a new line of text to get information for the second getchar() to read.

Given what the POSIX standard says, maybe a better demonstration is needed, and the Linux documentation should be clarified.

demo-fflush2.c

#include <stdio.h>

int main(void)
{
    int c;
    if ((c = getchar()) != EOF)
    {
        printf("Got %c\n", c);
        ungetc('B', stdin);
        ungetc('Z', stdin);
        if ((c = getchar()) == EOF)
        {
            fprintf(stderr, "Huh?!\n");
            return 1;
        }
        printf("Got %c after ungetc()\n", c);
        fflush(stdin);
    }
    if ((c = getchar()) != EOF)
        printf("Got %c\n", c);

    return 0;
}

Example output

Note that /etc/passwd is a seekable file. On Ubuntu, the first line looks like:

root:x:0:0:root:/root:/bin/bash

On Mac OS X, the first 4 lines look like:

##
# User Database
# 
# Note that this file is consulted directly only when the system is running

In other words, there is commentary at the top of the Mac OS X /etc/passwd file. The non-comment lines conform to the normal layout, so the root entry is:

root:*:0:0:System Administrator:/var/root:/bin/sh

Ubuntu 14.04 LTS:

$ ./demo-fflush2 < /etc/passwd
Got r
Got Z after ungetc()
Got o
$ ./demo-fflush2
Allotrope
Got A
Got Z after ungetc()
Got B
$

Mac OS X 10.11.2:

$ ./demo-fflush2 < /etc/passwd
Got #
Got Z after ungetc()
Got B
$

The Mac OS X behaviour ignores (or at least seems to ignore) the fflush(stdin) (thus not following POSIX on this issue). The Linux behaviour corresponds to the documented POSIX behaviour, but the POSIX specification is far more careful in what it says — it specifies a file capable of seeking, but terminals, of course, do not support seeking. It is also much less useful than the Microsoft specification.

Summary

Microsoft documents the behaviour of fflush(stdin), but that behaviour has changed between 2015 and 2021. Apparently, it works as documented on the Windows platform, using the native Windows compiler and C runtime support libraries.

Despite documentation to the contrary, it does not work on Linux when the standard input is a terminal, but it seems to follow the POSIX specification which is far more carefully worded. According to the C standard, the behaviour of fflush(stdin) is undefined. POSIX adds the qualifier 'unless the input file is seekable', which a terminal is not. The behaviour is not the same as Microsoft's.

Consequently, portable code does not use fflush(stdin). Code that is tied to Microsoft's platform may use it and it may work as expected, but beware of the portability issues.

POSIX way to discard unread terminal input from a file descriptor

The POSIX standard way to discard unread information from a terminal file descriptor (as opposed to a file stream like stdin) is illustrated at How can I flush unread data from a tty input queue on a Unix system. However, that is operating below the standard I/O library level.

🌐
Educative
educative.io › answers › what-is-fflush-in-c
What is fflush in C?
The fflush function in C is used to immediately flush out the contents of an output stream.
🌐
Post.Byes
post.bytes.com › home › forum › topic
What does fflush(stdin) do? - Post.Byes
So this will compile but its behavior is undefined by the ANSI C standard. The fflush() function is only meant to be used on streams open for output, not input. Both fflush(stdin) and fflush(NULL), in some C libraries, will flush stdout and stderr, but this is completely unportable!
Top answer
1 of 2
10

In a normal C program running on a modern OS, file access is buffered twice (or more when you count buffers like the buffer in your drive). One buffer is implemented in the FILE structure and the other is implemented in the kernel.

Often, the FILE structure buffers the content in a buffer inside of your program. When you write something to a buffered file, the content is keep in the buffer, inside of the running program. It is written to the OS when the buffer is full and, when the buffering mode is line buffered, at the end of a line. This data is written to the OS by a syscall, for example write(). The buffer is there because a syscall requires a context switch from the user program to the kernel, this is relatively expensive (slow), the buffer is here to reduce the number of syscalls. You could also use the syscalls from your program directly without the stdio functions, however, this functions are less portable and more complex to handle. A fflush(stdout) checks if there are any data in the buffer that should be written and if so, the underlying syscall is used to write the data to the OS.

When the syscall returns, the data is in your kernel. But modern operating systems buffer this data as well. This is used to reduce the number of disk writes, reduce latency and other things. This buffer is completely independent of the FILE buffer inside your program.

Note that this does not apply to all systems. For example microcontroller environments may provide some stdio.h functions that write directly to a UART, without any buffer, neither inside FILE nor any (probably non-existent) OS.

To see what fflush() does to a running program, compare this programs:

int main(void)
{
  fputs("s",stdout);
  fputs("e",stderr);
}

and

int main(void)
{
  fputs("s",stdout);
  fflush(stdout);
  fputs("e",stderr);
}

On Linux, stderr is not buffered by default, so fputs("e",stderr); will print the data immediately. On the other hand, fputs("s",stdout); is line buffered by default on Linux so the data is not printed immediately. This causes the first program to output es and not se, but the second one outputs se.

You can change the buffer modes with setvbuf()

2 of 2
5

When stdout points to a tty, it is, by default, line-buffered. This means the output is buffered inside the computer internals until a full line is received (and output).

Your programs do not send a full line to the computer internals.

In the case of using fflush() you are telling the computer internals to send the current data in the buffer to the device; without fflush() you are relying on the computer internals to do that for you at program termination.

By computer internals I mean the combination of the C library, Operating System, hardware interface, (automatic) buffers between the various interfaces, ...

🌐
OnlineGDB
question.onlinegdb.com › 16865 › fflush-stdin-meaning-in-c
fflush(stdin) meaning? in c - OnlineGDB Q&A
The purpose of fflush() is to clear or flush the buffer. However, according to the C standard: · fflush() is only guaranteed to work on output streams (like stdout)