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

为何用fscanf读取文件首行后fgets无法读取第二行?添加\n为何有效?

为什么fscanf读取后fgets无法读取第二行?

这个问题本质是stdio输入函数的缓冲区行为导致的,我来给你一步步拆解清楚:

1. fscanf的读取残留问题

当你用fscanf读取file.txt里的123 456 789 101时,它的工作逻辑是:

  • 自动跳过开头的空白字符(这里没有,直接读第一个数字)
  • 依次匹配四个%d格式,读取123、456、789、101
  • 当读完最后一个数字101后,文件指针会停在101后面的换行符位置(假设你的文件首行是这串数字,换行后是第二行内容)

这个换行符并没有被fscanf处理,而是留在了输入缓冲区里。

2. fgets的读取逻辑“踩坑”

fgets的规则是从当前指针位置开始读取,直到遇到换行符或EOF,并且会把换行符也包含到结果字符串里。这时候它一上来就碰到了缓冲区里残留的换行符,直接就把这个换行符读进来,返回一个只包含\n的空字符串。你看起来就像是“无法读取第二行”,但实际上它读了,只是读的是那个残留的换行符,不是你想要的第二行内容。

3. 为什么格式字符串加\n能解决问题?

当你在fscanf的格式字符串里加上\n(比如"%d %d %d %d\n"),fscanf会把\n解释为“跳过所有后续的空白字符”——这里的空白包括换行、空格、制表符等。它会一直跳过这些空白,直到碰到非空白字符或者EOF。

这样一来,那个残留的换行符就被彻底“吃掉”了,文件指针会直接移动到第二行的开头位置。这时候再调用fgets,就能正常读取第二行的内容了。

其他可选解决方案

除了加\n,你也可以在fscanf之后手动清除缓冲区里的残留换行,比如用一段小代码:

int c;
// 循环读取字符,直到碰到换行或文件结束
while ((c = fgetc(fp)) != '\n' && c != EOF);

这个方法更灵活,不会因为格式字符串的写法限制而出现问题。

内容的提问来源于stack exchange,提问作者J.Roe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:00:38