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

修改配置文件值后残留多余字符的解决方法及程序优化咨询

问题原因

你遇到的残留问题本质是新写入的字符串长度短于原行长度:原行name3 = value3(含换行符)的长度比新行name3 = 89长,用fputs写入新内容后,原行未被覆盖的剩余字符就留在了文件里。

修复现有代码的方法

针对当前代码,有两种优雅的解决思路:

方法1:填充空白覆盖残留

计算原行与新行的长度差,写入对应数量的空格覆盖残留字符:

#include <stdio.h>
#include <string.h>

#define MAX_LEN 64

int main(void)
{
        FILE *fp = fopen("a.txt", "r+");
        char line[MAX_LEN];
        long l = 89;
        size_t orig_len;

        while (fgets(line, MAX_LEN, fp)) {
                orig_len = strlen(line);
                if (strncmp(line, "name3", 5) == 0) {
                        fseek(fp, -orig_len, SEEK_CUR);
                        sprintf(line, "name3 = %ld\n", l); // 保留换行符维持行结构
                        size_t new_len = strlen(line);
                        fputs(line, fp);
                        // 用空格覆盖原行剩余字符
                        if (orig_len > new_len) {
                                for (size_t i = 0; i < orig_len - new_len; i++) {
                                        fputc(' ', fp);
                                }
                        }
                        goto close;
                }
        }
close:
        fflush(fp);
        fclose(fp);
}

方法2:截断文件

写入新内容后,直接截断文件到当前写入位置,丢弃后续残留字符:

#include <stdio.h>
#include <string.h>
#include <unistd.h> // POSIX系统头文件,Windows改用<io.h>和_chsize

#define MAX_LEN 64

int main(void)
{
        FILE *fp = fopen("a.txt", "r+");
        char line[MAX_LEN];
        long l = 89;

        while (fgets(line, MAX_LEN, fp)) {
                if (strncmp(line, "name3", 5) == 0) {
                        fseek(fp, -strlen(line), SEEK_CUR);
                        sprintf(line, "name3 = %ld\n", l);
                        fputs(line, fp);
                        // 获取当前位置并截断文件
                        long pos = ftell(fp);
                        ftruncate(fileno(fp), pos); // Windows替换为_chsize(fileno(fp), pos)
                        goto close;
                }
        }
close:
        fflush(fp);
        fclose(fp);
}
更优的程序写法

直接修改原文件的方式容易出现残留、中途崩溃损坏文件等问题,更可靠的是采用**「读入内存→修改→重写文件」**的模式:

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

#define MAX_LINE_LEN 64
#define BUF_SIZE 1024 // 根据文件实际大小调整

int main(void)
{
        FILE *src_fp = fopen("a.txt", "r");
        if (!src_fp) {
                perror("打开源文件失败");
                return 1;
        }

        // 读取全部内容到缓冲区
        char buf[BUF_SIZE] = {0};
        fread(buf, 1, BUF_SIZE - 1, src_fp);
        fclose(src_fp);

        // 逐行处理并修改目标内容
        char *line = strtok(buf, "\n");
        char *output = malloc(BUF_SIZE);
        if (!output) {
                perror("内存分配失败");
                return 1;
        }
        output[0] = '\0';

        while (line != NULL) {
                if (strncmp(line, "name3", 5) == 0) {
                        strcat(output, "name3 = 89\n");
                } else {
                        strcat(output, line);
                        strcat(output, "\n");
                }
                line = strtok(NULL, "\n");
        }

        // 写入回原文件
        FILE *dst_fp = fopen("a.txt", "w");
        if (!dst_fp) {
                perror("打开目标文件失败");
                free(output);
                return 1;
        }
        fputs(output, dst_fp);
        fclose(dst_fp);
        free(output);

        return 0;
}

这种模式的优势:

  • 避免直接修改原文件的风险,中途崩溃不会损坏原始数据
  • 逻辑清晰,彻底杜绝字符残留问题
  • 适合绝大多数小型配置文件的修改场景

如果文件过大不适合一次性读入内存,可以改用「逐行写入临时文件→修改完成后替换原文件」的方式,核心逻辑一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:15:55