为何用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
相关产品推荐
相关产品推荐

