C语言scanf语句吃掉回车或者空格问题及解决
作者:Z小旋
问题描述
我们经常在C语言输入的时候,会发现scanf讲空格或者回车“吃掉”了,导致程序的运行结果与预期不一致
以下面一个简单例子为例
#include<stdio.h> char str[10]; int main() { int i; for(i=0;i<10;i++) { scanf("%c",&str[i]); } for(i=0;i<10;i++) { printf("%c",str[i]); } return 0; }
这个程序,获取10个数,然后打印出来
如果我们正常的输入10个字符,打印正常
如果我们输入a,然后回车,再输入b,再回车… ,结果只能输入5个字符,这就是我们经常说的Scanf吃掉了你的回车
那么我们首先来了解一下scanf语句:
scanf
scanf()函数是格式输入函数,即按用户指定的格式从标准输入设备(键盘) 上把数据输入到指定地址的变量中。
读取方式:
一般格式为:scanf(格式控制,地址列表) 也就是scanf("%?",&?); 可以读取相对于类型的数值并且存储到制定变量,并且可以读取多个数值,如数字,字符,字符串等 ,每次用到scanf‘时,他都会从数据缓存区读取一个或多个字符,并存入相对应的变量中
注意:
- scanf()在读取数字时会跳过空格、制表符和换行符!
- %c只能输出或输入一个字符,%s输出的是一串字符还有就是char a; string s;输入的时候scanf("%c",&a);这里的&不能少,而scanf("%s",s);这里不能有&符号
重点:
scanf遇到 回车(enter),空格,TAB 就会结束一次输入,空格不会接收
并且, scanf在一次输入结束后,不会舍弃最后的回车符(即回车符会残留在数据缓冲区中)
看下方程序
#include <stdio.h> int main(){ char c1,c2; scanf("%c %c",&c1,&c2); //这里有一个空格 printf("%d %d\n",c1,c2); scanf("%c%c",&c1,&c2); //这里没有空格 printf("%d %d\n",c1,c2); return 0; }
第一次输入a和b正常,没有问题,但是第二次就出现问题了,
scanf单字符输入时规定只接收一个字符,所以第一次输入a b 时 ,第一个scanf("%c %c")之间有一个空格,所以在输入字符a之后,我们可以输入空格,enter,,scanf都会自动忽略它(那个空格会读取停止字符并释放掉),所以第一次输入正常,但它却把回车符也作为字符对待的。
在我们输入完b之后按回车(Enter),这个回车符是放在缓冲区的,并且不会舍弃最后的回车符,此时的数据缓存区中还残存着一个回车符,
第二次调用scanf("%c%c",&c1,&c2);是从缓冲区中取两个字符,首先把第一次调用scanf("%c%c",&c1,&c2);后输入的回车当作输入字符赋值给c1 ,之后把a赋值给了c2
这就在输入逻辑上造成了混乱。
我们这样改一下
#include <stdio.h> int main(){ char c1,c2; scanf("%c %c",&c1,&c2); //这里有一个空格 printf("%d %d\n",c1,c2); scanf(" %c %c",&c1,&c2); //这里也有了空格 printf("%d %d\n",c1,c2); return 0; }
在第二个scanf中添加了两个空格 然后我们正常输入
scanf(" %c",&c)前面这个空格(换成\n或者\t也可以),这样就把缓冲区中的回车当成第一个字符,读取后丢掉
可以很好理解scanf中 空格的作用
空格( )即为读取一个结束字符然后丢掉,而普通的字符不受影响
用好之后可以避免很多程序BUG
那么现在各位应该知道上方的程序怎么改了
在对应位置加好空格就可以了,
这个问题的解决虽然简单,但是整个问题出现与解决的原因,才是我们需要学习的,不能只拘束与添加一个空格,而应该清楚的明白其内部的原理,这是我们学习所必须的一个品质。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。