Reputation: 1160
This is my program:
#include <iostream>
int main()
{
// open file1.txt
FILE* file1;
fopen_s(&file1, "file1.txt", "wb+");
// write array of 5 integers to file.txt
int array1[5] { 1, 2, 3, 4, 5 };
for (int i = 0; i < 5; i++)
{
fwrite(array1, sizeof(array1[0]), 5, file1);
}
fseek(file1, 0, SEEK_SET);
int tempValue;
fread(&tempValue, sizeof(tempValue), 1, file1);
// fseek(file1, 0, SEEK_CUR);
fwrite(&tempValue, sizeof(tempValue), 1, file1);
}
At runtime the program crashed with informatoin:
> Expression ("Flush between consecutive read and write.",
> !stream.has_any_of(_IOREAD))
But if I uncomment fseek(file1, 0, SEEK_CUR);
everything would be fine considering file pointer has not been moved. So why is that?
I use Visual Studio 2019
P.S. Why this works just fine?
#include <iostream>
int main()
{
FILE* file1;
fopen_s(&file1, "data.txt", "wb+");
int value = 7;
fwrite(&value, sizeof(value), 1, file1);
fwrite(&value, sizeof(value), 1, file1);
fseek(file1, 0, SEEK_CUR);
fwrite(&value, sizeof(value), 1, file1);
fread(&value, sizeof(value), 1, file1);
}
Upvotes: 1
Views: 1092
Reputation: 93
Pulled from Microsofts C Runtime Library documentation
When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed. (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.
Changing between read/write operations require a file-position function, In your code snippet, you have:
...
fseek(file1, 0, SEEK_SET);
int tempValue;
fread(&tempValue, sizeof(tempValue), 1, file1);
// fseek(file1, 0, SEEK_CUR);
fwrite(&tempValue, sizeof(tempValue), 1, file1);
...
Since you are changing from read to write, you need to call a file-position function (fsetpos, fseek or rewind).
As for write to read, you will still need to call a file-position function. However to answer why the second code block works, we need to know what fwrite() does on success.
According to the same Microsoft documentation,
... The fwrite function writes up to count items, of size length each, from buffer to the output stream. The file pointer associated with stream (if there is one) is incremented by the number of bytes actually written.
Consider the code that you have provided:
...
FILE* file1;
fopen_s(&file1, "data.txt", "wb+");
int value = 7;
fwrite(&value, sizeof(value), 1, file1);
fwrite(&value, sizeof(value), 1, file1);
fseek(file1, 0, SEEK_CUR);
fwrite(&value, sizeof(value), 1, file1);
fread(&value, sizeof(value), 1, file1);
...
Assuming all fwrite()'s succeed, your file pointer would be at the EOF. Since the input operation encounters EOF, the code block would execute just fine.
However, you should follow guidelines and call fsetpos, fseek or rewind should fwrite fail.
C standard library corner case
Why is fseek or fflush always required between reading and writing in the update modes?
Upvotes: 1