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

C语言写入指定首字符行到文件时仅输出1行的问题修复

问题说明

待实现的C程序功能要求:

  • 接收用户输入的指定字母
  • 读取源文件story.txt中的所有行
  • 将所有以该输入字母开头的整行,追加写入目标文件letter.txt
    当前程序故障表现:运行时仅写入1条匹配行就停止执行,即便源文件中存在多条符合首字符匹配规则的行也无法正常处理。
    原问题代码:
#include <stdio.h>
#include <string.h>
int main()
{
    FILE* f = fopen("story.txt","r");
    char usr;
    printf("enter letter: ");
    scanf(" %c",&usr);

    FILE* f2=fopen("letter.txt","a+");

    char buffer[255];
       while(fscanf(f, "%[^\n]s", buffer)==1)
        if (*buffer == usr)
          fprintf(f2, "%s\n", buffer);

    return 0;
}
故障根因

核心bug出在fscanf的格式符使用逻辑:
%[^\n]的匹配规则是读取连续的非换行符字符,遇到换行符立即停止,但不会将触发停止的换行符从文件流中移除。第一次读取完成后,文件指针正好停在第一行末尾的换行符位置,下一轮循环调用fscanf时,第一个读取到的字符就是换行符,直接不满足%[^\n]的匹配规则,函数返回0,循环直接终止,这就是程序永远只会处理第一行内容的原因。
原代码还存在三个易触发崩溃的隐患:

  • 未做文件打开结果校验,若story.txt不存在会直接触发空指针访问崩溃
  • fscanf未设置最大读取长度,遇到长度超过254字符的行时会溢出buffer,造成内存错误
  • 操作完成后未关闭文件流,可能导致写入内容未落盘、文件句柄泄漏
  • 格式符%[^\n]s末尾的s是多余写法,%[]本身就是独立的格式说明符,不需要额外拼接s
修复方案

推荐直接用更适合逐行读取场景的fgets替代fscanf,自动处理换行符读取逻辑,同时补全边界校验,修复后完整代码如下:

#include <stdio.h>
#include <string.h>
int main()
{
    FILE* f = fopen("story.txt","r");
    if (f == NULL) {
        perror("open story.txt failed");
        return 1;
    }
    char usr;
    printf("enter letter: ");
    scanf(" %c",&usr);

    FILE* f2=fopen("letter.txt","a+");
    if (f2 == NULL) {
        perror("open letter.txt failed");
        fclose(f);
        return 1;
    }

    char buffer[255];
    while(fgets(buffer, sizeof(buffer), f) != NULL)
    {
        if (buffer[0] == usr) {
            fputs(buffer, f2);
        }
    }

    fclose(f);
    fclose(f2);
    return 0;
}

如果一定要保留fscanf的写法,只需要在每次fscanf读取完成后,额外把流里残留的换行符读走即可,同时给格式符加长度限制避免溢出,循环部分修改如下:

while(fscanf(f, "%254[^\n]", buffer)==1)
{
    // 消费掉流中残留的换行符
    fgetc(f);
    if (*buffer == usr)
        fprintf(f2, "%s\n", buffer);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 21:06:35