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

C语言文本文件中fseek()可靠性及搭配ftell()用法的相关疑问

关于C语言文本模式下fseek()的常见问题解答

为什么fseek()在文本文件中无法保证任意偏移都正常运行

C标准中,文件打开分为文本模式和二进制模式两种,二者的核心差异就是文本模式会自动处理系统相关的特殊字符转换:

  • 比如Windows平台下文本文件的换行实际存储为\r\n两个字节,文本模式读取时会自动合并为单个\n返回,写入时又会把\n拆成\r\n写入
  • 部分旧系统还会存在文本文件结束符、行尾填充字符等其他特殊转换规则

这种转换会导致你读写时感知到的逻辑位置,和文件实际物理存储的字节位置不匹配,而C标准没有要求标准库支持文本模式下的任意数值偏移寻址,只有两种fseek操作是被标准明确保证安全的:

  • 偏移量为0,相对于文件开头寻址(SEEK_SET),即直接回到文件头
  • 偏移量为之前ftell()返回的有效值,相对于文件开头寻址

其他所有用法(比如自己随便填偏移量、相对于当前位置SEEK_CUR/文件末尾SEEK_END做非0偏移)都属于未定义行为,这就是大家常说fseek不能随便用在文本文件上的原因。

先调用ftell()存位置再用fseek()跳回的用法是否正确

这个说法是正确的,完全符合C标准要求。
ftell()在文本模式下返回的不是普通的物理字节偏移,而是标准库内部维护的、可以唯一标识文件位置的特殊标记值,这个值的唯一用途就是传给fseek()搭配SEEK_SET使用,保证可以准确跳转到之前记录的位置。
注意你提到的代码存在笔误,标准正确写法如下:

// 记录当前文件位置
long pos = ftell(file);
// 中间执行其他文件读写操作
// 跳转回之前记录的位置
fseek(file, pos, SEEK_SET);

这种用法无论在文本模式还是二进制模式下都是完全安全的。

读写回写场景的额外注意事项

如果你需要在同一个文件流上交替执行读和写操作,每次切换操作类型之前,必须调用fflush()、fseek()、fsetpos()或者rewind()做同步,否则行为是未定义的,读写原文件的场景很容易踩到这个坑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:36:01