You need to enable JavaScript to run this app. C语言fscanf读取文件时仅能读取单行的问题排查与解决方法
优惠活动
大模型
产品
解决方案
定价
更多

C语言fscanf读取文件时仅能读取单行的问题排查与解决方法

fscanf仅读取一行即终止的问题排查

核心诱因

  • 代码本身缺失循环读取结构:当前逻辑仅执行一次fscanf调用就走到打印流程,随后程序直接退出,从执行流程上就不存在读取20余行内容的可能,哪怕读取功能完全正常,也只会读一次数据就终止。
  • fscanf格式串存在副作用:使用的fscanf(read,"%s\n",Sound.choice)里的\n,实际作用是匹配任意数量的连续空白字符(换行、空格、制表符),直到碰到第一个非空白有效字符才停止匹配,并非“跳过单个换行”。如果读到文件末尾没有后续非空白内容,这个匹配会直接触碰文件结束符,触发读取中断。
  • 缺少必要的安全防护:直接用%s不限制读取长度,很容易因为输入字符串过长导致数组越界,破坏栈内存;直接把读到的字符串作为printf的参数,如果内容里带%格式符,会引发未定义行为。

修正方案

  • 调整fscanf格式串:去掉末尾的\n,给%s加上和结构体数组长匹配的读取长度限制,比如choice数组长度是16,就写成%15s,留1个字节存字符串结束符,避免越界。
  • 增加循环读取逻辑:把单次fscanf调用放到while循环中,通过fscanf的返回值判断读取是否成功,只要成功匹配到预期数量的字段就继续处理,直到碰到文件结束。
  • 修正打印逻辑:不要直接把读到的字符串作为printf的格式串,改成显式的字符串占位写法printf("%s\n", Sound.choice)。
  • 补充健壮性判断:增加文件打开失败的分支判断,读完数据后调用fclose()关闭文件流,避免空指针操作和资源泄漏。

修正后的参考代码:

#include <stdio.h>

struct soundInput{
    char choice[16];
    char type[7];
    char sound[10];
    char sound2[10];
};

int main() {
    struct soundInput Sound;
    FILE *read = fopen("input.txt", "r");
    if (read == NULL) {
        perror("打开input.txt失败");
        return 1;
    }
    // 循环读取,fscanf成功匹配1个字符串时持续运行
    while (fscanf(read, "%15s", Sound.choice) == 1) {
        printf("%s\n", Sound.choice);
    }
    fclose(read);
    return 0;
}

注意:如果input.txt是按行存储的、每行包含空格的完整文本,fscanf %s是按空白分割字段的,并不会按整行读取,这类场景更适合用fgets逐行读入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.07 09:36:08