简体   繁体   中英

cant write to file after using fgetc/getc (Windows)

I'm developing on Windows (VS 2010) a simple program using fgetc and I recognized that after I'm using this function (same behavior with getc) I can't write to the file although I opened it with appropriate permissions.

Here is a simple program I wrote to check what the hell is going on:

int main(int argc, char * argv[]) 
{
    FILE *f = NULL;
    char ch = 0;
    int bytes = 0;

    f = fopen(argv[1], "r+");
    ch = fgetc(f);
    bytes = fwrite("1234", sizeof(char), 4, f);
    printf("%d", bytes);
    fflush(f);
    fclose(f);

    system("PAUSE");
    return 0;
}

The program prints 4 and exit without any error, but the file content remain the same. After I research it a little bit I found out that if I add this line (that doing "nothing"):

fseek(f, 0, SEEK_CUR);

The program working as I expected, and the file content changed.

all the code after adding this line:

int main(int argc, char * argv[]) 
{
    FILE *f = NULL;
    char ch = 0;
    int bytes = 0;

    f = fopen(argv[1], "r+");
    ch = fgetc(f);
    fseek(f, 0, SEEK_CUR)
    bytes = fwrite("1234", sizeof(char), 4, f);
    printf("%d", bytes);
    fflush(f);
    fclose(f);

    system("PAUSE");
    return 0;
}

Does anyone know why is this happen and how to solve it?

Thanks a lot, Hanan.

It does not work because the C standard (C11 draft n1570 7.21.5.3 in The fopen function paragraph 7 ; and all previous versions as well) says it does not have to work.

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


Notice that if the file was initially empty , then fgetc would have returned EOF and "1234" would have been written.

From https://msdn.microsoft.com/en-us/library/yeby3zcb.aspx

When the "r+", "w+", or "a+" access type is specified, both reading and writing are enabled (the file is said to be open for "update"). However, when you switch from reading to writing, the input operation must encounter an EOF marker. If there is no EOF, you must use an intervening call to a file positioning function. The file positioning functions are fsetpos, fseek, and rewind. When you switch from writing to reading, you must use an intervening call to either fflush or to a file positioning function

So because you probably haven't hit EOF then you need to position the seek position so your call to fseek is exactly what you needed.

The comments on the return code from fgetc are important too but aren't affecting your code at the moment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM