yadav_vi
yadav_vi

Reputation: 1297

Problems with r+ mode in fopen()

I was trying out the various modes of opening a file in C. I am stuck a little at the modes of r+, w+ and a+.

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

int main(void)
{
    .....
    /* make a file with something in it */
    if( (fp = fopen( filename, "w" )) )
    {
        fprintf( fp, "abcd" );
        fclose( fp );
    }
    /* see how r+ works */
    if( (fp = fopen( filename, "r+" )) )
    {
        int c = 0;

        /* read something */
        c = fgetc( fp );
        printf( "c is %c\n", c );

        /* write something */
        fseek( fp, -1, SEEK_CUR );
        fputc( 'x', fp );
        fflush(fp);

        /* read something */
        c = fgetc( fp );
        printf( "c is %c\n", c );

        /* rewind and show the whole thing */
        rewind( fp );
        while( (c = fgetc( fp )) != EOF )
        {
            printf( "c is %c\n", c );
        }

        fclose(fp);
    }

    return 0;
}

This gives me the following output -
c is a
c is b
c is x
c is b
c is c
c is d

Even if I remove the fflush() here -

/* write something */
fseek( fp, -1, SEEK_CUR );
fputc( 'x', fp );
//fflush(fp);

it gives me the same output. So how come I am able to write without fflush() on the output stream?(Am I right that fputc() writes on the output stream?) Also, can I use fflush() instead of fseek() in the above code snippet?

Upvotes: 0

Views: 1521

Answers (1)

Crowman
Crowman

Reputation: 25908

Per C11 7.21.5.3.7:

When a file is opened with update mode ... 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.

The fact that you get the same input without your fflush() call is not guaranteed by the standard (although some implementations, including glibc, allow it, so it's not all that surprising to see it work here).

For your other question, no, you can't use fflush() instead of fseek() here, because your fseek() comes before an output operation, not an input operation. fflush() is only meaningful for output streams, and for update streams where the most recent operation was not input.

Upvotes: 2

Related Questions