Reputation: 71
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:
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
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