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

scanf与fgets的行为差异及fgets少读一行的问题咨询

scanf与fgets的行为差异及fgets少读一行的问题咨询

嗨,这个问题我之前也碰到过,其实核心原因就是输入缓冲区里残留的换行符在搞鬼!

为什么会少读一行?

我猜你应该是先用类似 scanf("%d", &lines); 的代码获取了lines的值吧?当你输入数字(比如5)然后按回车的时候,这个回车产生的\n换行符并没有被scanf("%d")吃掉,它会留在标准输入缓冲区里。

当你接着调用fgets循环时,第一个fgets会直接把这个残留的\n当作一行空内容读走,然后才开始读你后续实际输入的内容。这样一来,总共读的行数里就包含了这一行空的,实际有效输入就少了一行,看起来像是只读了4行而不是5行。

而你之前用的scanf(" %[^\n]", s[i]),注意格式串最前面的那个空格——这个空格会让scanf自动跳过所有空白字符(包括换行、空格、制表符),所以它会直接忽略掉缓冲区里残留的那个换行符,能精准读满lines行内容。

怎么解决这个问题?

这里给你两个简单靠谱的解决办法:

  • 方法一:先清空输入缓冲区再调用fgets
    在启动fgets循环之前,把缓冲区里残留的换行符(以及可能的其他空白字符)全部读掉。可以用这段代码:
// 清理缓冲区里的残留空白字符,直到读到换行或文件结束
int c;
while ((c = getchar()) != '\n' && c != EOF);

这样处理后,后续的fgets就能从你实际输入的内容开始读,不会被残留的换行符坑到了。

  • 方法二:换用fgets读取lines的值,从根源避免残留换行
    如果你不想处理缓冲区的问题,也可以直接用fgets来读取lines的输入,再转换成整数。这样整个输入流程都用行读取的方式,不会残留换行符在缓冲区里:
char num_buf[20];
// 先读入包含数字的一行
fgets(num_buf, sizeof(num_buf), stdin);
// 把字符串转成整数
lines = atoi(num_buf);

之后再调用fgets循环读内容,就能正常读满lines行了。

你可以试试这两种方法,亲测有效!

备注:内容来源于stack exchange,提问作者Vinayak Deshmukh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 09:18:05