How to put garbage in output buffer to use fflush()?

The documentation for fflush() doesn't define "output buffer" nor "input buffer" nor what "flushing" them actually does. Also, it doesn't provide a reference in the "See also" section where I can read about io buffers.

I read about it in cplusplus's "Input/Output with Files" tutorial article which suggests they are allocated memory to store bytes to be written out to a stream (or to be read from a stream). So it seems that buffers are something like a data structure that stores characters/bytes before they're written out from (or into) memory. Flushing would then mean emptying out this data structure so that it contains nothing. (Source: http://www.cplusplus.com/doc/tutorial/files/)

Also, suppose this "data structure" exists, what mechanism transfers data in these buffers to the physical file? When does that transference take place? (I suspect there's a system call in the implementation of the library that pauses program execution to accomplish this task).

Ultimately, I'm trying to get a better idea of what fflush() does and the example doesn't suffice. What would help, I think, is a code example in which you explicitly put garbage in the buffer and use fflush() to clear it.

What would help, I think, is a code example in which you explicitly put garbage in the buffer and use fflush() to clear it.

The fflush() function doesn't "clear" the buffer it flushes (writes) the buffer to the output device. The effect on an input buffer is not defined by the standard.

Also, suppose this "data structure" exists, what mechanism transfers data in these buffers to the physical file?

The runtime system flushes the output buffer to the output device when several different "triggers" occur. These triggers are the buffer is full, your program calls the fflush() function, or the output stream is closed.

What would help, I think, is a code example in which you explicitly put garbage in the buffer and use fflush() to clear it.
There is no garbage involved. What is being handled is valid file data which is merely stored on a temporary basis in the buffer rather than in the physical file. The aim is to increase system performance by avoiding using many physical file accesses.

Each time the user program code writes to the file, what actually happens is the data is added to the buffer. Eventually the buffer will be full, at which point the entire contents are written to the file in one go, then the data is once more added to the buffer. When the file is closed, the contents of the buffer are written to the physical file if it is not empty - it need not be full.
Last edited on
Thanks for the explanation, Chervil. That did help me understand the buffer better. Unfortunately, it doesn't help me see why fflush() in the code below helps the program "pause" correctly.

The code compiles and runs fine except at the end where gets(a) gets called. Without fflush(), the program runs the last printf() and the console window exits abruptly. I added fflush() because I figured the last call to printf() left something in the buffer which gets picked up by gets() as soon as its called. Not sure if this is what actually happens though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* Filename Chap3 A.c*/
/* Totals how much money will be spent on holiday gifts. */

#include<stdio.h>

int main()
{	
	float gift1=0, gift2=0, gift3=0, gift4=0, gift5=0, total=0; /*initialization*/
	
	printf("How much do you want to spend on your mom?");
	scanf ("%f", &gift1);
	printf("\nHow much do you want to spend on your dad?");
	scanf("%f", &gift2);
	printf("\nHow much do you want to spend on your brother?");
	scanf("%f", &gift3); 
	printf("\nHow much do you want to spend on your sister?");
	scanf("%f", &gift4);
	printf("\nHow much do you want to spend on yourself?");
	scanf("%f", &gift5);

	total=gift1+gift2+gift3+gift4+gift5;
	printf("\nThe total ammount you will be spending on your gifts is $%.2f", total);
	
	
	fflush(stdin);	//Flush the stream buffer so gets() doesn't just take garbage from 
					//stream and prematurely terminate. 
	
	//Pause console: Use this over system("pause"); 
	char a[10]; 
	gets(a); 
	
	return 0;
}


Last edited on
fflush(stdin) engenders undefined behaviour.

C, C++:
For input streams (and for update streams on which the last operation was input), the behavior is undefined.
http://en.cppreference.com/w/c/io/fflush


Implementations may provide non-portable extensions.

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.
https://linux.die.net/man/3/fflush


Microsoft:
If the stream was opened in read mode, or if the stream has no buffer, the call to fflush has no effect
https://msdn.microsoft.com/en-us/library/9yky46tz.aspx


BSD provides the non-standard fpurge:
The function fpurge() erases any input or output buffered in the given stream. For output streams this discards any unwritten output. For input streams this discards any input read from the underlying object but not yet obtained via getc(3); this includes any text pushed back via ungetc(3).
https://www.freebsd.org/cgi/man.cgi?query=fpurge&apropos=0&sektion=0&manpath=FreeBSD+10.2-RELEASE&arch=default&format=html


JLBorges wrote:
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.

that was actually wrong https://bugzilla.kernel.org/show_bug.cgi?id=91931 was my bug report about it. It now correctly says

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.

up-to-date Linux man pages are here http://man7.org/linux/man-pages/man3/fflush.3.html

Note they still do not describe what fflush(stdin) does normally, that is, if stdin is not redirected from a file. On Linux that does precisely nothing
Last edited on
ElusiveTau wrote:
(I suspect there's a system call in the implementation of the library that pauses program execution to accomplish this task).
Good call. If you use Linux, you can run your program under strace to observe exactly these system calls. I'll do it below

ElusiveTau wrote:
Ultimately, I'm trying to get a better idea of what fflush() does and the example doesn't suffice. What would help, I think, is a code example in which you explicitly put garbage in the buffer and use fflush() to clear it.

To put garbage somewhere, you have to get garbage from somewhere first.
1
2
3
4
5
int main() {
    char c; // garbage in a variable
    putchar(c); // garbage in the buffer
    fflush(stdout); // garbage on the screen.
}

But that won't help you see any effect of fflush - as with any proper buffered I/O, the results are the same as if you don't flush it.

What fflush exists for. It's for immediate output on a buffered C I/O stream:

1
2
3
4
5
6
7
8
9
10
#include <thread>
#include <chrono>
#include <cstdio>
using namespace std::literals;
int main()
{
    printf("stuff");
    std::this_thread::sleep_for(10s);
    printf("more stuff\n");
}

if you run this program, it sits there and waits 10 seconds, and then suddenly prints "stuffmorestuff"

strace will show that the output was in a single system call after the pause

nanosleep({tv_sec=10, tv_nsec=0}, NULL) = 0
write(1, "stuffmore stuff\n", 16) = 16


If you change that to

1
2
3
4
5
6
7
8
9
10
11
#include <thread>
#include <chrono>
#include <cstdio>
using namespace std::literals;
int main()
{
    printf("stuff");
    fflush(stdout);
    std::this_thread::sleep_for(10s);
    printf("more stuff\n");
}


then it prints "stuff" instantly, and 10 seconds later adds "more stuff" to the same line.

strace will show the system calls separated by the pause:
write(1, "stuff", 5) = 5
nanosleep({tv_sec=10, tv_nsec=0}, NULL) = 0
write(1, "more stuff\n", 11) = 11

Note that if you make it printf("stuff\n");, the endline will flush stdout (by default) and there would be no difference.. now you would have to learn about three buffering strategies used by the C I/O streams - see setbuf/setvbuf if you're that adventurous. One thing for certain, fflush(stdin) is nonsense (except when working with POSIX files that change under your feet).
Last edited on
> that was actually wrong ...
> up-to-date Linux man pages are here http://man7.org/linux/man-pages/man3/fflush.3.html

Thank you!
Topic archived. No new replies allowed.