带 SEEK_CUR 的 fseek() 函数中的零偏移有什么用?

问题描述 投票:0回答:1
while (fread(&product, sizeof(Product), 1, file) == 1) {
        product.price *= 2.0;
        fseek(file, -sizeof(Product), SEEK_CUR);
        fwrite(&product, sizeof(Product), 1, file);
        fseek(file, 0, SEEK_CUR);
}

使用上面的代码,我尝试将二进制文件中每个产品的价格加倍,其中每个记录都是 Product 结构的一个实例。当我运行这段代码时,它正确地更新了文件中的所有价格。

据我所知,

fread
自动将文件指针移动到下一条记录。使用第一个
fseek
,代码将文件指针移回记录的开头。然后它使用
fwrite
更新它。
fwrite
自动将文件指针移动到下一条记录。在while循环中,
fread
要继续读取下一条记录,以此类推

这里好像不需要

fseek(file, 0, SEEK_CUR);
。但是,如果我删除它,代码将进入无限循环。我不知道为什么会这样。

我尝试使用

ftell
观察文件指针的值。但是在
fseek(file, 0, SEEK_CUR);
之后我没有看到它的值有任何变化。

c file fseek
1个回答
2
投票

当一个流同时打开读写时,不能直接切换读写。 §7.21.5.3 ISO C11 标准的¶7 规定如下:

当文件以更新模式打开时(“+”作为上述模式参数值列表中的第二个或第三个字符),可以在关联流上执行输入和输出。但是,如果没有对 fflush 函数或文件定位函数(fseek、fsetpos 或 rewind)的干预调用,则输出不应直接跟随输入,并且如果没有对文件定位的干预调用,输入不应直接跟随输出函数,除非输入操作遇到文件结尾。

如果你删除线

fseek(file, 0, SEEK_CUR);

那么您的程序将违反此规则,这将调用 undefined behavior。这意味着任何事情都可能发生,包括您的程序陷入无限循环的可能性。

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