Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to flush my I/O stream to get the correct result?

Tags:

c

iostream

Why the code below does not work? I mean, it shows all kinds of weird characters on console output.

#include <stdio.h>
char mybuffer[80];
int main()
{
    FILE * pFile;
    pFile = fopen ("example.txt","r+");
    if (pFile == NULL) perror ("Error opening file");

    else {
        fputs ("test",pFile);

        fgets (mybuffer,80,pFile);
        puts (mybuffer);
        fclose (pFile);
        return 0;
    }
}

However, the code below works well.

#include <stdio.h>
char mybuffer[80];
int main()
{
    FILE * pFile;
    pFile = fopen ("example.txt","r+");
    if (pFile == NULL) perror ("Error opening file");

    else {
        fputs ("test",pFile);
        fflush (pFile);    
        fgets (mybuffer,80,pFile);
        puts (mybuffer);
        fclose (pFile);
        return 0;
    }
}

Why I need to flush the stream in order to get the correct result?

like image 521
Jaebum Avatar asked Feb 09 '10 16:02

Jaebum


People also ask

What does flushing a stream do?

Flushing a stream ensures that all data that has been written to that stream is output, including clearing any that may have been buffered. Some streams are buffered to aid performance, e.g. a stream writing to disk may buffer until the content reaches a block size.

What is the purpose of flush function?

C++ manipulator flush is used to synchronize the associated stream buffer with its controlled output sequence. For the stream buffer, objects that implement intermediate buffers, flush function is used to request all characters written to the controlled sequence.

What is flush () Java?

The flush() method of PrintWriter Class in Java is used to flush the stream. By flushing the stream, it means to clear the stream of any element that may be or maybe not inside the stream. It neither accepts any parameter nor returns any value.

Does cout flush automatically?

It is an implementation detail, one that invariably depends on whether output is redirected. If it is not then flushing is automatic for the obvious reason, you expect to immediately see whatever you cout. Most CRTs have an isatty() helper function that is used to determine whether automatic flushing is required.


2 Answers

Because the standard says so (§7.19.5.3/5):

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

There is a reason for this: output and input are normally buffered separately. When there's a flush or seek, it synchronizes the buffers with the file, but otherwise it can let them get out of synch. This genarally improves performance (e.g. when you do a read, it doesn't have to check whether the position you're reading from has been written since the data was read into the buffer).

like image 62
Jerry Coffin Avatar answered Oct 06 '22 00:10

Jerry Coffin


When using a file with a read/write mode you must call fseek/fflush before different i/o operations.

See this answer on why fseek or fflush is always required...

like image 45
Robert Groves Avatar answered Oct 05 '22 23:10

Robert Groves