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

