tags:

views:

136

answers:

3

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?

+2  A: 

its because C file io works using a buffer. This is only written to disk when you flush it, you write a /n character or you fill the buffer up.

So in the first case, your file contains nothing when you come to read from it.

gbjbaanb
But it still does not work even if I use "test\n" instead of "test".
Lee Jae Beom
The answer is wrong in this regard: Writing `\n` to the file has no effect at all; you must flush the file or write so much data that the C library will flush by itself (usually 4KiB).
Aaron Digulla
I think the \n bit depends on the implementation - MS does, at least for C++ code.
gbjbaanb
+7  A: 

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

Robert
Thx; I should've search harder
Lee Jae Beom
+10  A: 

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

Jerry Coffin
Thx a lot !!!!!!
Lee Jae Beom
But why the output of the second source is not "test" ?It just shows nothing..
Lee Jae Beom
@Lee: Simple, you read it from the point where you left off writing, you need to seek back to the beginning for that to work.
roe
@Lee:because the "Test" that you wrote hasn't been read into the read buffer. A probable scenario is that when you open the file, it attempts to fill the read buffer. Since the file is empty, it sets a flag to say no input is available. Until you do a flush or seek, it's going to remain marked that way, so all attempts at reading will fail.
Jerry Coffin
Thx for the comment Jerry :)
Lee Jae Beom