问题
当我们在使用一个很平常的循环来读取字符时,scanf函数总是不能给我们带来想要的效果,如下面一个简单的例子:
1 |
|
这段代码的功能是读取用户的输入的6个字符,因此我们想要的是下图中的效果:
但是当我们实际运行时的效果却不是这样,如下图所示,出现了输入次数减半的情况,只输入三次就结束了,而循环的次数应该是六次!
出现原因
为什么会出现这种情况?这与scanf中%c的性质有关,下面这段话来自K&R:
c,字符;char*类型,将接下来的多个输入字符(默认为一个字符)存放到指定位置。该转换规范通常不跳过空白符。
可以看到%c会读取空白符! 也就是说在scanf中用%c来解说会将回车键这一类的空白符读入,在我们输入一个字符’a’后再按下回车键,此时就相当于输入了两个字符:‘a’和’\n’。因此就完成了两次循环读入,所以只输入了三次就结束了,另外三次用于读取了回车符’\n’。
解决方法
找到原因后就好解决了,这里提供了3种方法:
- 在scanf函数后面加入一行getchar函数,用来读取回车符。
1 | for(i = 0; i < 6; i++) { |
- 使用赋值静止符%*c来跳过回车符。
1 | for(i = 0; i < 6; i++) { |
- 使用%1s来替换%c读取字符,可以读取下一个非空白符。
1 | for(i = 0; i < 6; i++) { |
- 在%c前加一个空格变成” %c”形式,,提示scanf忽略输入流中的空白符。(常用)
1 | for(i = 0; i < 6; i++) { |
总结
这个问题的关键所在就是空白符也属于字符,scanf函数也会读取,因此在处理输入有空白符的问题时要多加小心,避免出错,在下面这种情况中也要使用同样的方法来消除空白符。
1 | scanf("%c", &a); |