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

C语言fprintf更新文件时覆盖下一行首字符的问题求助

问题分析与解决方案

问题根源

你判断的完全正确,bug确实出在更新文件开头{nbrSalles}的代码段。核心原因是:

  • 当nbrSalles为个位数时(比如9),写入的{9}占3个字符;
  • 当它增长到10及以上时,{10}会占用4个字符。
    在"r+"模式下,文件写入是覆盖式而非插入式,多出来的1个字符会直接覆盖下一行的首个字符,导致你看到的异常。

解决方案

提供两种可靠修复方式,可根据场景选择:

方案1:预留固定长度数字位

初始化和更新数字时,强制让数字占固定宽度(比如3位),确保无论数字大小,写入的字符长度一致,避免覆盖后续内容。

修改代码中两处写入数字的fprintf:

  • 文件初始化时:
fprintf(f,"{%03d}\n",nbrSalles += 1); // 固定3位,不足补0,例如{001}、{010}
  • 更新数字时:
fprintf(f,"{%03d}",nbrSalles); // 同样用%03d格式化

读取逻辑无需额外修改,fscanf(f,"{%d}\n",&nbrSalles)会自动忽略前导零,正常解析数字。

方案2:全文件内容重写

如果不想用固定位数格式,可以先把文件全部内容读入内存,修改开头数字后清空文件,再重新写入所有内容。这种方式更灵活,但大文件会占用较多内存。

修改else分支的逻辑:

else {
    // 读取文件全部内容到内存
    rewind(f);
    fseek(f, 0, SEEK_END);
    long file_size = ftell(f);
    rewind(f);
    
    char* file_content = malloc(file_size + 1);
    if (!file_content) {
        fclose(f);
        return;
    }
    fread(file_content, 1, file_size, f);
    file_content[file_size] = '\0';
    
    // 解析并更新nbrSalles
    fscanf(f,"{%d}\n",&nbrSalles);
    nbrSalles += 1;
    
    // 清空文件并重新写入
    ftruncate(fileno(f), 0);
    rewind(f);
    
    // 写入更新后的数字
    fprintf(f,"{%d}\n",nbrSalles);
    
    // 写入原文件中除开头数字外的内容
    char* newline_pos = strchr(file_content, '\n');
    if (newline_pos) {
        fprintf(f,"%s", newline_pos + 1);
    }
    
    // 写入新Piece数据(原写入逻辑移至此处)
    test = testeChaine(TEMP_FILE,file);
    if(test==1){
        fprintf(f,"[%d|%d]%d\n",p->height, p->width, p->id);
    }else{
        fprintf(f,"[%d|%d]%d\n",p->height, p->width, p->id+nbrSalles-1); // 注意nbrSalles已+1,需回退
    }
    
    for(int i = 0; i < p->height; i +=1 ){
        for(int j = 0; j < p->width; j +=1 ){
            fprintf(f,"%c ",p->piece[i][j]);
        }
        fprintf(f,"\n");
    }
    
    free(file_content);
}

额外优化点

  • 原代码中fopen使用的"rw+"并非标准C模式,建议改为标准的"r+"(读写,文件需存在)或"w+"(读写,创建/截断文件);
  • 建议添加文件操作的返回值检查(比如fseek、fprintf的返回值),提前捕获隐藏错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:50:36