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

C语言替换txt文件指定行时输入待修改行号后程序自动退出如何解决

问题原因及修复方案

问题产生原因

代码里的问题主要是以下几个错误叠加导致的程序崩溃:

  • 最直接的崩溃原因:scanf("%d ", line); 没有传入line变量的地址,scanf读取数值类输入要求传入目标变量的指针,你直接传入了未初始化的line值作为内存地址,触发非法内存访问,直接导致程序退出。
  • path被定义为const char数组,后续调用strcat修改该数组内容,属于修改只读内存,会触发运行时异常。
  • Ic被定义为int[12]类型,但你用gets读取字符串输入,类型完全不匹配,写入数据会破坏内存布局,进一步引发异常。
  • scanf的格式字符串"%d "末尾多了一个空格,会导致scanf读取完数字后持续忽略所有空白字符,直到读到非空白字符才返回,会造成后续输入逻辑异常。
  • 额外问题:gets是C标准已经废弃的危险函数,存在缓冲区溢出风险;fflush(stdin)是未定义行为,仅在部分特定编译器下生效,不具备通用性。

修复方案

按照以下步骤修改代码即可解决问题:

  1. 去掉path数组的const修饰,允许后续拼接路径字符串。
  2. 将Ic的类型从int[12]改为char[13],用字符数组存储IC号字符串,多预留1位存储字符串结束符\0。
  3. 替换危险的gets函数为fgets,读取IC号后手动去掉末尾的换行符,避免路径拼接出错。
  4. 修改scanf调用,添加&取地址符,删除格式串末尾的空格,读取完成后手动消耗输入缓冲区残留的换行符,避免后续fgets直接读空。

注意:使用strcspn需要提前引入<string.h>头文件。

修正后的关键代码片段

void UpdateCustomerPortfolio()
{
    // 去掉const修饰,允许修改
    char path[500] = "C:\\Users\\jason\\Desktop\\College stuff\\Final assessment\\Fundimentals of programming\\Accounts\\";
    // 改为char数组存储字符串
    char Ic[13];
    int line;
    char txt[5] = ".txt",num[100];
    FILE * fPtr;
    FILE * fTemp;
    char buffer[BUFFER_SIZE];
    char newline[BUFFER_SIZE];
    int count;
    
    printf("Input IC number: ");
    // 替换gets为fgets
    fgets(Ic, sizeof(Ic), stdin);
    // 去掉fgets读取的末尾换行符
    Ic[strcspn(Ic, "\n")] = '\0';
    
    strcat(path, Ic);
    strcat(path, txt);
    
    system("cls");
    
    printf("Enter the Information that requires an update:");
    printf("\n[01]First Name");
    printf("\n[02]Last Name");
    printf("\n[04]Home Address");
    printf("\n[05]Contact Number");
    printf("\n[06]Email Address\n");
    // 添加取地址符&,去掉格式串末尾空格
    scanf("%d", &line);
    // 手动消耗缓冲区残留的换行符,不要用fflush(stdin)
    while(getchar() != '\n');

    printf("Replace '%d' line with: ", line);
    fgets(newline, BUFFER_SIZE, stdin);
    // 可选:去掉newline末尾多余的换行符,按需开启
    // newline[strcspn(newline, "\n")] = '\0';


    /*  Open all required files */
    fPtr  = fopen(path, "r");
    fTemp = fopen("replace.tmp", "w"); 

    /* fopen() return NULL if unable to open file in given mode. */
    if (fPtr == NULL || fTemp == NULL)
    {
        /* Unable to open file hence exit */
        printf("\nUnable to open file.\n");
        printf("Please check whether file exists and you have read/write privilege.\n");
        exit(EXIT_SUCCESS);
    }


    /*
     * Read line from source file and write to destination 
     * file after replacing given line.
     */
    count = 0;
    while ((fgets(buffer, BUFFER_SIZE, fPtr)) != NULL)
    {
        count++;

        /* If current line is line to replace */
        if (count == line)
            fputs(newline, fTemp);
        else
            fputs(buffer, fTemp);
    }


    /* Close all files to release resource */
    fclose(fPtr);
    fclose(fTemp);

    /* Delete original source file */
    remove(path);

    /* Rename temporary file as original file */
    rename("replace.tmp", path);

    printf("\nSuccessfully replaced '%d' line with '%s'.", line, newline);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:24:02