为什么我对fwrite()和fread()有麻烦?

问题描述 投票:0回答:1

这是我的程序:

#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);
}
c++ fwrite fread
1个回答
0
投票

读写]

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或倒带。


类似的Stackoverflow问题

C standard library corner case

Why is fseek or fflush always required between reading and writing in the update modes?

© www.soinside.com 2019 - 2024. All rights reserved.