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

C语言修改文件中STORAGE_后序列号写入报错问题咨询

C语言修改文件中STORAGE_后序列号写入报错问题咨询

嘿,我来帮你排查这个写入报错的问题!你当前的代码在读取并处理行内容时是正常的,但一启用fputs写入就出问题,核心原因是**r+模式下读写指针的处理逻辑错误**,加上直接原地修改文件的潜在风险,具体拆解如下:

问题根源

  • 读写指针不同步:r+模式下文件的读、写指针是共享的。你用fgets读取一行后,指针已经移动到下一行开头,这时调用fputs会把内容写到当前指针位置(也就是下一行),而非覆盖原来的目标行,直接导致文件内容混乱,甚至触发文件访问错误。
  • 行长度变化的隐患:原行格式是"STORAGE_7253":,处理后变成"STORAGE_1":,长度明显变短,原行剩余的字符(比如3":)会残留下来,形成"STORAGE_1"3":这类错误格式,同时长度变化会导致后续内容错位。
  • VS安全机制限制:VS的文件操作函数对读写切换有严格要求,读写之间如果没有用fseek或fflush同步指针,会触发未定义行为,直接引发报错。

推荐解决方法:临时文件中转(最稳妥)

直接修改原文件容易损坏数据,用临时文件中转是最安全的方案,处理完成后替换原文件即可:

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

#define MAX_LINE_LENGTH 1000

int main() {
    FILE* fp_src;
    FILE* fp_temp;
    char line[MAX_LINE_LENGTH];
    char* pos;
    int num;
    const char* src_path = "C:/Users/13383/Desktop/storage.txt";
    const char* temp_path = "C:/Users/13383/Desktop/storage_temp.txt";

    // 打开原文件只读
    if (fopen_s(&fp_src, src_path, "r") != 0) {
        printf("打开原文件失败:%d\n", errno);
        exit(1);
    }
    // 打开临时文件写入
    if (fopen_s(&fp_temp, temp_path, "w") != 0) {
        printf("创建临时文件失败:%d\n", errno);
        fclose(fp_src);
        exit(1);
    }

    while (fgets(line, MAX_LINE_LENGTH, fp_src) != NULL) {
        pos = strstr(line, "STORAGE_");
        if (pos != NULL) {
            // 提取STORAGE_后的数字
            num = atoi(pos + strlen("STORAGE_"));
            num -= 7252;
            // 定位原数字后的引号,保证格式正确
            char* quote_pos = strchr(pos + strlen("STORAGE_"), '"');
            if (quote_pos != NULL) {
                sprintf_s(pos + strlen("STORAGE_"), quote_pos - (pos + strlen("STORAGE_")), "%d", num);
            }
        }
        // 将处理后的行写入临时文件
        fputs(line, fp_temp);
    }

    // 关闭文件句柄
    fclose(fp_src);
    fclose(fp_temp);

    // 替换原文件
    if (remove(src_path) != 0) {
        printf("删除原文件失败:%d\n", errno);
        remove(temp_path);
        exit(1);
    }
    if (rename(temp_path, src_path) != 0) {
        printf("重命名临时文件失败:%d\n", errno);
        remove(temp_path);
        exit(1);
    }

    printf("处理完成!\n");
    return 0;
}

可选方案:原地修改原文件(不推荐)

如果能保证处理后的行长度和原行完全一致(比如原数字是4位,修改后也为4位),可以尝试原地修改,但风险较高:

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

#define MAX_LINE_LENGTH 1000

int main() {
    FILE* fp;
    char line[MAX_LINE_LENGTH];
    char* pos;
    int num;
    long current_pos;

    if (fopen_s(&fp, "C:/Users/13383/Desktop/storage.txt", "r+") != 0) {
        printf("打开文件失败\n");
        exit(1);
    }

    while ((current_pos = ftell(fp)) != -1 && fgets(line, MAX_LINE_LENGTH, fp) != NULL) {
        pos = strstr(line, "STORAGE_");
        if (pos != NULL) {
            num = atoi(pos + strlen("STORAGE_"));
            num -= 7252;
            // 注意:必须保证修改后的数字长度和原数字一致,否则会损坏文件
            sprintf_s(pos + strlen("STORAGE_"), MAX_LINE_LENGTH - (pos - line) - strlen("STORAGE_"), "%d\"", num);
            
            // 将指针移回当前行开头
            fseek(fp, current_pos, SEEK_SET);
            // 写入处理后的行
            fputs(line, fp);
            // 刷新缓冲区同步指针
            fflush(fp);
        }
    }

    fclose(fp);
    printf("处理完成!\n");
    return 0;
}

额外提示

  • 临时文件方案几乎不会出错,无论行长度如何变化都能正确处理,且中途出错时原文件不会损坏。
  • 原地修改仅适用于行长度完全不变的场景,一旦长度变化会直接导致文件内容错位、损坏。

备注:内容来源于stack exchange,提问作者KabiLink

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 12:10:32