C语言中用fwrite()、fseek()覆盖文件指定位置内容失败求助
解决fwrite() + fseek()无法覆盖文件内容的问题
哦,这个问题我之前也踩过坑!核心原因是你用了"a+"模式打开文件——这个模式的设计就是不管你怎么fseek,所有写操作都会强制追加到文件末尾,这是C标准明确规定的行为,和POSIX忽略'b'完全没关系。
为什么"a+"模式不行?
"a+"是追加读写模式,它的核心特性就是:所有写操作执行前,文件指针会被自动定位到文件末尾。哪怕你手动调用fseek跳转到了文件中间的位置,当你执行fwrite时,系统会偷偷把指针移回文件尾,所以你写的内容只会追加到最后,根本不会覆盖中间的字节。这个设计是为了保证多进程/线程同时追加文件时的安全性,但显然不符合你要修改文件中间内容的需求。
正确的解决方案
改用"r+"(读写模式)或者"rb+"(二进制读写模式,兼容Windows)打开文件即可:
"r+"模式支持任意位置的读写操作,fseek定位到哪里,fwrite就从哪里开始覆盖内容。"rb+"中的'b'在POSIX系统中会被忽略,但在Windows下会禁用文本模式的换行符转换,避免因换行符导致字节偏移计算错误,推荐使用这个模式来保证跨平台兼容性。
修改后的完整代码
#include <stdio.h> int main() { // 用rb+模式打开文件,兼顾POSIX和Windows平台 FILE *fp = fopen("file.txt", "rb+"); if (fp == NULL) { perror("Failed to open file"); return 1; } // 定位到第10个字节(注意:C中文件字节从0开始计数,对应你说的第10位) if (fseek(fp, 10, SEEK_SET) != 0) { perror("fseek failed"); fclose(fp); return 1; } // 写入"ABCD",覆盖从偏移10开始的4个字节 size_t written_bytes = fwrite("ABCD", 1, 4, fp); if (written_bytes != 4) { perror("fwrite failed"); fclose(fp); return 1; } // 务必关闭文件,确保内容刷新到磁盘 fclose(fp); return 0; }
额外注意事项
"r+"和"rb+"模式不会创建新文件,如果目标文件不存在,fopen会返回NULL,所以要提前确保文件存在。- 执行完写操作后一定要调用
fclose(),否则缓冲区的内容可能不会及时写入磁盘,导致修改不生效。
内容的提问来源于stack exchange,提问作者Frodo
相关产品推荐
相关产品推荐

