C语言操作数字文件时用fprintf追加内容出现乱码如何解决
问题原因与解决方案
核心错误点
- memset使用错误:你在调用
memset(line,0,strlen(line))时,line是刚定义的未初始化栈数组,内容是随机垃圾值,strlen(line)会从数组首地址开始查找\0计算长度,返回值完全随机,根本没有正确清空整个数组。应该直接用数组总长度作为memset的第三个参数,即sizeof(line)。 - 读写操作未同步:C语言标准明确规定,对于以更新模式(带
+的打开模式,比如a+、r+)打开的文件,输入操作和输出操作之间必须调用fseek/rewind定位文件指针,或者调用fflush刷新缓冲区,否则行为是未定义的。你的代码中fgets读完内容后直接调用fprintf写入,没有做任何同步操作,这是产生乱码的核心原因。 a+模式的写入特性未考虑:a+模式的所有写入操作都会强制追加到文件末尾,不受当前读指针位置影响,如果你需要在文件中间插入内容,a+模式无法满足需求。如果只是需要在末尾追加读到的第二行内容,也需要做好读写同步。- 缺少文件关闭操作:函数结束前没有调用
fclose(arquive)关闭文件,会导致缓冲区内容没有完全刷入磁盘,同时产生资源泄漏。 - 缺少文件打开成功判断:
fopen可能因为权限、路径不存在等原因返回NULL,直接操作会导致程序崩溃。
修复后代码
以下是实现「读取文件第二行内容追加到文件末尾」需求的修复代码:
#include <stdio.h> #include <string.h> void change(char* file) { int count = 0; FILE* arquive = fopen(file,"a+"); // 先判断文件是否打开成功 if (arquive == NULL) { perror("fopen failed"); return; } char line[256]; // 清空整个数组 memset(line, 0, sizeof(line)); char auxLine[256]; memset(auxLine, 0, sizeof(auxLine)); while (fgets(line, sizeof(line), arquive) != NULL) { if (count == 1) { strncpy(auxLine, line, sizeof(auxLine) - 1); // 读写切换前显式同步,定位到文件末尾 fseek(arquive, 0, SEEK_END); fprintf(arquive, "%s", auxLine); // 仅写入一次,直接跳出循环 break; } else { count++; } } // 关闭文件,刷新缓冲区 fclose(arquive); }
额外说明
如果你的需求不是追加到末尾,而是要在文件中间插入内容,不能直接在原文件上修改,正确做法是:
- 新建一个临时文件
- 逐行读取原文件内容,写入临时文件,在需要的位置插入你要加的内容
- 删除原文件,将临时文件重命名为原文件名
内容的提问来源于stack exchange,提问作者Another
相关产品推荐
相关产品推荐

