You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fseek函数SEEK_CUR模式下0偏移的作用?移除后为何死循环

为什么移除fseek(file, 0, SEEK_CUR)会导致死循环?

以下代码用于将二进制文件中每个Product结构体实例的价格翻倍,原本可正常运行:

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);
}

按逻辑推导:

  • fread读取完一条记录后,文件指针会自动跳至下一条记录的起始位置
  • 第一个fseek将指针移回当前记录开头,方便fwrite覆盖更新
  • fwrite完成后,指针又会自动跳至下一条记录位置,照理说下一次fread应该能继续读取下一条,循环正常推进

但实际测试发现,移除fseek(file, 0, SEEK_CUR);后代码会进入死循环,用ftell观察发现这条语句执行前后指针值完全没变,实在搞不懂它的必要性。


问题根源:标准库的流同步规则

这是因为在读写操作交替进行时,流的位置状态可能处于未定义状态,必须通过fseek或fsetpos这类操作来同步位置状态。

虽然ftell显示指针值没变化,但fseek(file, 0, SEEK_CUR)的核心作用不是移动指针,而是强制让标准库同步内部的读写位置缓存:

  • 当你先执行fread再切换到fwrite时,流的状态从"读模式"切换到"写模式",此时标准库的内部位置指针可能处于模糊状态——它知道当前字节位置,但未明确完成读写状态的切换同步。
  • 如果直接再次调用fread,标准库可能无法正确更新位置,导致下一次fread又读取了刚刚修改过的同一条记录,从而进入死循环。
  • fseek(file, 0, SEEK_CUR)看似没移动指针,但它会触发流的位置同步,让标准库明确当前的位置状态,确保下一次fread能正确读取下一条记录。

简单说,这条语句是给标准库一个"明确位置、切换状态"的信号,表面上没动指针,但内部完成了必要的同步操作,避免了死循环。

内容的提问来源于stack exchange,提问作者osmangokalp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:32:06