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

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

额外说明

如果你的需求不是追加到末尾,而是要在文件中间插入内容,不能直接在原文件上修改,正确做法是:

  1. 新建一个临时文件
  2. 逐行读取原文件内容,写入临时文件,在需要的位置插入你要加的内容
  3. 删除原文件,将临时文件重命名为原文件名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 15:54:07