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

为何调用fgetc()后需额外添加fseek()才能使fputc()生效?

为什么在fgetc()后直接调用fputc()无效,添加fseek(fp,0,SEEK_CUR)却能正常工作?

在使用r+模式打开文件后,执行以下操作时遇到异常:

  1. 用fseek(fp, 4, SEEK_SET)将文件指针定位到第4位
  2. 调用fgetc()读取字符,此时指针移动到第5位
  3. 直接调用fputc()写入新字符,文件无任何变化
    但在fputc()前添加fseek(fp, 0, SEEK_CUR)(无实际位移)后,写入操作正常生效。

原代码如下:

#include <stdio.h>
#include <stdlib.h>

int main() {
FILE *fp;
char ch;
char c[100];

fp = fopen("file12.txt", "r+");
if (fp == NULL) {
    printf("ERROR");
    exit(1);
}

fseek(fp, 4, SEEK_SET);
printf("%c", fgetc(fp));

// fseek(fp, 0, SEEK_CUR);
fputc('M', fp);

fclose(fp);
return 0;
}

原因分析

这是C标准库文件流操作的读写切换规则导致的:

  • 当文件以更新模式(r+)打开时,标准明确规定:在没有先执行定位函数(fseek/fsetpos/rewind)或刷新函数(fflush)的情况下,不能直接从读操作切换到写操作,反之亦然。
  • 你先执行了fgetc()读操作,此时流处于读状态,直接调用fputc()属于违规切换,行为是未定义的(可能被忽略、覆盖错误位置或导致其他异常)。
  • fseek(fp, 0, SEEK_CUR)虽然没有改变指针的实际位置,但它属于标准认可的定位操作,会触发流状态的切换,让库正确处理后续的写操作,因此fputc()能正常写入到目标位置。

补充说明:C17标准§7.21.5.3章节明确了这一规则——更新流上的读操作和写操作之间必须有一个定位或刷新操作,否则行为未定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:42:18