【C语言】scanf语句吃掉回车或者空格问题详解

c语言学习 专栏收录该内容
14 篇文章 26 订阅

问题描述:

我们经常在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个字符,打印正常
ru'guo

如果我们输入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

那么现在各位应该知道上方的程序怎么改了

在这里插入图片描述
在对应位置加好空格就可以了,

这个问题的解决虽然简单,但是整个问题出现与解决的原因,才是我们需要学习的,不能只拘束与添加一个空格,而应该清楚的明白其内部的原理,这是我们学习所必须的一个品质。

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值