C语言循环执行5次但仅响应2次字符输入的问题排查
问题分析与解决方案
这个问题我太熟啦,本质是输入缓冲区的残留空白字符在搞鬼!
为什么会出现只响应2次输入的情况?
当你用scanf("%d", &t)读取数字5时,它只会把数字本身读走,而输入中数字后面的**空格(或换行符)**会留在输入缓冲区里。接下来每次循环执行scanf("%c", &c)时,它会直接读取这些残留的空白字符,而不是你输入的字母。这些空白字符不匹配任何if条件,所以不会输出内容。
你输入的b f c b f这5个字母里,只有第2个和第4个字母被实际读取到了(因为它们前面的空白被先读走了),所以程序只输出了两次结果。
最简单的修复方法
在读取字符的scanf格式串前加一个空格,修改后的代码如下:
#include <stdio.h> int main() { int t; scanf("%d",&t); while (t--) { char c; scanf(" %c",&c); // 这里加了一个空格 if(c =='b' || c== 'B') printf("BattleShip\n"); else if(c=='c' || c=='C') printf("Cruiser\n"); else if(c == 'd' || c=='D') printf("Destroyer\n"); else if(c=='f' || c=='F') printf("Frigate\n"); } }
这个空格的作用是告诉scanf:先跳过所有的空白字符(空格、换行、制表符都包含在内),直到遇到第一个非空白字符再读取,这样就完美避开了缓冲区残留的空白干扰。
测试验证
当你输入5 b f c b f时,修复后的程序会输出:
BattleShip
Frigate
Cruiser
BattleShip
Frigate
完全符合你的预期!
其他可选方案
如果你不想用空格的方式,也可以在读取数字后用getchar()吃掉缓冲区里的残留字符,但这种方法在输入格式多变时(比如用户换行输入)不如加空格可靠。示例代码如下:
#include <stdio.h> int main() { int t; scanf("%d",&t); getchar(); // 吃掉数字后的空白字符 while (t--) { char c; scanf("%c",&c); if(c =='b' || c== 'B') printf("BattleShip\n"); else if(c=='c' || c=='C') printf("Cruiser\n"); else if(c == 'd' || c=='D') printf("Destroyer\n"); else if(c=='f' || c=='F') printf("Frigate\n"); getchar(); // 吃掉每个字母后的空白字符 } }
不过这种方法需要处理每个输入后的空白,不如第一种方法简洁,所以更推荐加空格的方案。
内容的提问来源于stack exchange,提问作者Rohan Jaiswal




