Search code examples
cwindowsfilegccfputs

Why when read and write performed back to back in file opened in rb+ mode behaves not as expected in c language


I opened a file in rb+ mode successfuly Wrote two strings using two fputs. File ptr moved to 3 byte from file beginning using fseek. Read four characters successfuly using fgets. Now when I tried to write third string using fputs I am unable to do so. Why is this happening

#include<stdio.h>

int main(int argc, char *argv[])
{
    FILE *fp;

    if( argc != 2)
    {
        printf("NOT ENOUGH ARGUMENTS");
        return 1;
    }

    fp = fopen(argv[1], "rb+");
    if(fp == NULL)
    {
        fp = fopen(argv[1], "wb+");
        if( fp == NULL )
        {
            printf("\nUNABLE TO CREATE FILE");
            return 2;
        }
        else
        {
            printf("\nFILE CREATED SUCCESSFULLY");
        }
    }
    else
    {
        printf("\nFILE OPENED SUCCESSFULLY");
    }

    char str[100];

    fseek(fp, 0, SEEK_END);
    fputs("123456789", fp);
    fputs("ABCDEFGH", fp);
    fseek(fp, 3, SEEK_SET);
    //fputs("hello", fp);
    fgets(str, 4, fp);
    printf("\n%s\n",str);
    fputs("why", fp);

    fseek(fp, 0, SEEK_END);
    printf("\nTHE SIZE OF FILE IS : %ld", ftell(fp));
    fclose(fp);

    return 0;
}

when commented out code is added it works as expected


Solution

  • The stdio functions support buffering data instead of calling the OS for every operation, and this makes it more complicated to support intermixed reads and writes. You can get in a situation where some of the data in the buffer matches what's on the disk, and some of it doesn't. It would be possible for the implementers to code the library to make it work, but it adds complexity and cost, and so the designers of the C standard chose to not require it. And moreover, existing implementations probably didn't support it. So the standard included the requirement that the program needs to seek, which typically will flush those buffers, and then the issue doesn't arise. – Nate Eldredge