Behrad Elmi
Behrad Elmi

Reputation: 71

fprintf is not working properly in Visual Studio (C programming)

I was working with files in visual studio (2015 professional) when I got to this problem

take a look at this code:

#include <stdio.h>
int main()
{
    char a;
    FILE* H = fopen("data.txt", "w+");
    if (fgetc(H) == EOF)
    {
        fprintf(H, "A");
        fseek(H, 0, SEEK_SET);
    }
    if (( a = fgetc(H)) == 'A')
    {
        fprintf(H, "B");
    }
    fclose(H);
}

The problem was that "A" was being written on data.txt file, but B was not. I tried running the code on debug mode. It went to the second "if" and then reached fprintf(H, "B") but still no luck and B wasn't being written on the file. The next thing I did was to check out the return value of fprintf, so I tried this code:

#include <stdio.h>
    int main()
    {
        char a;
        int err;
        FILE* H = fopen("data.txt", "w+");
        if (fgetc(H) == EOF)
        {
            fprintf(H, "A");
            fseek(H, 0, SEEK_SET);
        }
        if (( a = fgetc(H)) == 'A')
        {
            err = fprintf(H, "B");
        }
        fclose(H);
    }

The err was showing 1 as the return value of fprintf(H, "B") but the only thing that was being written on data.txt was still A. what I've anticipated out of this code was:

  1. data.txt to be created
  2. fgetc to read EOF (since there is nothing written on the file yet it is true)
  3. A to be written
  4. pointer to be moved to start of file (behind A in the file)
  5. in the second if "A" to be read by fgetc and pointer of the file to be moved one character forward
  6. At the end B to be written after A in the data.txt file

Well... all of that happened except the last one. I reached out to people who were using different compilers other than visual studio However, for them, this code was working perfectly fine, and the result was "AB" being written on the file. Later on when I used fseek to move the pointer of file it pretty much solved the problem, but I'm still wondering why it didn't work without fseek being involved, logically everything looks fine to me though I'm not sure why its not working in visual studio. (by the way for those who seek the fix with fseek :) here's the code)

#include <stdio.h>
int main()
{
    char a;
    int err;
    FILE* H = fopen("data.txt", "w+");
    if (fgetc(H) == EOF)
    {
        fprintf(H, "A");
        fseek(H, 0, SEEK_SET);
    }
    if ((a = fgetc(H)) == 'A')
    {
        fseek(H, 0, SEEK_CUR);
        err = fprintf(H, "B");
    }
    fclose(H);
}

Upvotes: 1

Views: 490

Answers (1)

Weather Vane
Weather Vane

Reputation: 34585

C18 § 7.21.5.3 says (my bolding)

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

This is why the writing of "B" after reading 'A' did not work correctly, and adding fseek() in accordance with the C standard, allowed it to work.

Upvotes: 3

Related Questions