这是我的程序:
#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);
}
在运行时程序崩溃并显示信息:
> Expression ("Flush between consecutive read and write.",
> !stream.has_any_of(_IOREAD))
但是如果我取消评论fseek(file1, 0, SEEK_CUR);
考虑到文件指针尚未移动,一切都会很好。那为什么呢?我使用Visual Studio 2019
P.S。为什么这样可以正常工作?
#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);
}
从Microsofts C Runtime Library documentation中拉出
指定了“ r +”,“ w +”或“ a +”访问类型时,将允许进行读取和写入。 (据说该文件已打开以进行“更新”。)但是,当从读取切换为写入时,输入操作必须遇到EOF标记
。如果没有EOF,则必须对文件定位功能进行中间调用。文件定位功能是fsetpos,fseek和rewind。 当从写入切换为读取时,必须使用中间调用来进行fflush或文件定位功能。在读/写操作之间进行更改需要文件位置功能,在您的代码段中,您有:
... fseek(file1, 0, SEEK_SET); int tempValue; fread(&tempValue, sizeof(tempValue), 1, file1); // fseek(file1, 0, SEEK_CUR); fwrite(&tempValue, sizeof(tempValue), 1, file1); ...
由于要从读取更改为写入,因此需要调用文件位置函数(fsetpos,fseek或快退)。
关于读写操作,您仍然需要调用文件位置函数。但是,要回答第二个代码块为何起作用的情况,我们需要知道fwrite()成功执行的工作。
根据same Microsoft documentation,
... fwrite函数最多写入从缓冲区到输出流的计数项,每个项的大小长度。与流关联的文件指针(如果有的话)增加实际写入的字节数。
考虑您提供的代码:
... 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); ...
假设所有fwrite()成功,则您的文件指针将位于EOF处。Since the input operation encounters EOF,该代码块将正常执行。
但是,您应该遵循准则并呼叫fsetpos,如果fwrite失败,请致电fseek或倒带。
C standard library corner case
Why is fseek or fflush always required between reading and writing in the update modes?