Thread: r+ in fopen doesnt let me read and write at the same time

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    120

    r+ in fopen doesnt let me read and write at the same time

    Hello.

    When I open a file using fopen, and i set the mode to r+ (that supposedly allows me to read and write in that file at the same time), and then when i try to read or write in it, only the first thing i try works, for example:

    Code:
    int main() {
    
        FILE *file;
        
        file = fopen("test.txt", "r+");
        char a = fgetc(file);
        fputc('a', file);
        
        printf("%c", a);
        fclose(file);
    
    }
    in this case, only fgetc() would be succesfully executed, while fputc would be ignored. If I put fputc() first and then fgetc(), then it would be fgetc() the ignored function?

    What am I doing wrong here? why cant i read and write at the same time?

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    What does your file have in it? It doesn't automatically rewind the file every time you read or write. What are you actually trying to do?


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    120
    the file has only the text "bbbbb"

    I now found out that when i try to do fputc() and then fgetc() the char that fgetc() was suposed to get gets messed up inside the file :\

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Well, right off you shouldn't be reading and writing text files at the same time. These are *sequences* of characters, read and write happen in relation to a single file pointer. To open the file then immediately do fputc() will overwrite the first character and advance the file pointer... fgetc() is now indexed to the second character so you end up getting the wrong data.... Reversing that, doing fgetc() first will fetch the first character and advance the file pointer so that your second character gets clobbered with fputc().

    Best bet for human readable files... don't try to mix read and write operations together. (For the reasons you've just discovered)
    Last edited by CommonTater; 09-04-2011 at 07:48 PM.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    120
    I know that very well, but the thing is that it is not behaving that way. When i put a char and then try to read the 2 char.. it simply doesnt read it, instead it messes up the char that it was s thats the problem.

    I usualy dont use input and output at the same time for a file, but since this is not working as i expected, i want to know what am i doing wrong. Am i using the r+ the wrong way?

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    The problem is actually with the position of the file pointer after doing the write:
    Code:
    #include<stdio.h>
    int main( void )
    {
        char filename[] = "rplustest.foo";
        FILE *fp = NULL;
    
        /* 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 */
            fputc( 'x', fp );
            fflush( fp );
            
            /* read something */
            fseek( fp, -1, SEEK_CUR );
            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 );
            }
        }
    
        return 0;
    }
    I believe your writes are happening at the end of the file in this mode, so without without seeking, reads following a write are off the end of your file.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    This might help... (From the Pelles C help file, emphasis mine...)
    fopen function

    Purpose:
    Opens a stream. The safer fopen_s function is also available.

    Syntax:
    FILE * fopen(const char *name, const char *mode);

    Declared in:
    <stdio.h>


    The fopen function opens the file whose name is the string pointed to by name, and associates a stream with it. The string may contain a full path (from the root), a relative path (from the current directory) or just a name.

    The argument mode points to a string. If the string is one of the following, the file is open in the indicated mode.

    Mode Description
    "r" Open text file for reading.
    "w" Truncate to zero length or create text file for writing.
    "a" Append; open or create text file for writing at end-of-file.
    "rb" Open binary file for reading.
    "wb" Truncate to zero length or create binary file for writing.
    "ab" Append; open or create binary file for writing at end-of-file.
    "r+" Open text file for update (reading and writing).
    "w+" Truncate to zero length or create text file for update.
    "a+" Append; open or create text file for update, writing at end-of-file.
    "rb+" Open binary file for update (reading and writing).
    "wb+" Truncate to zero length or create binary file for update.
    "ab+" Append; open or create binary file for update, writing at end-of-file.
    "r+b" Same as "rb+"
    "w+b" Same as "wb+"
    "a+b" Same as "ab+"

    Opening a file with read mode ('r' as the first character in the mode argument) fails if the file does not exist or cannot be read.

    Opening a file with append mode ('a' as the first character in the mode argument) causes all subsequent writes to the file to be forced to the then current end-of-file, regardless of intervening calls to the fseek function.

    When a file is opened with update mode ('+' as the second or third character in the mode argument), 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.

    When opened, a stream is fully buffered if and only of it can be determined not to refer to an interactive device. The error and end-of-file indicators for the stream are cleared.

    Returns:
    A pointer to the object controlling the stream on success, otherwise a null pointer.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    120
    Ahh, that helped indeed, that explains the behaviors i was getting both from my program and from quzah's.
    ok, my mind is at ease now thank you both.

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by shiroaisu View Post
    Ahh, that helped indeed, that explains the behaviors i was getting both from my program and from quzah's.
    ok, my mind is at ease now thank you both.
    No worries... looks like you dipped into Undefined Behaviour...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Read/Write file at the same time
    By doia in forum C Programming
    Replies: 2
    Last Post: 02-25-2010, 04:18 PM
  2. please help, can't read file, fopen
    By live4soccer7 in forum C Programming
    Replies: 16
    Last Post: 03-16-2009, 02:52 AM
  3. last write time
    By pastitprogram in forum C++ Programming
    Replies: 2
    Last Post: 07-31-2008, 06:54 PM
  4. read(), write() in GCC
    By Lord CyKill in forum C Programming
    Replies: 1
    Last Post: 09-24-2003, 11:10 PM