C语言——奇怪的scanf()方法(附加)

问题一:为什么我的第二个scanf( )函数被跳过”

例如:

#include <stdio.h>

int main()
{
	int a;
	char c;
	scanf("%d",&a);
	scanf("%c",&c);
	printf("%d %c",a,c); 
}

解析:当我们输入:123
会发现程序会“直接”打印整数123,好像并没有给我们留下时间和空间输入字符型变量c的值
但是可以发现,其实整型变量c已经读入了值‘\n’,即ASCII码为10的字符——换行符; :

实际上:

函数scanf( )从标准输入设备(键盘) 读取输入的信息,不会直接赋值给变量,而是先储存到一个缓冲区中;

当程序执行到函数scanf()时,程序会从缓冲区中读取
如果缓冲区是空的,才会停滞,光标闪烁,等待键盘的输入.

值得注意的是,scanf()中格式字符串里:
-对于参数%d会忽略缓冲区开头的空白符(空格、回车、制表符等);
-对于参数 %c:直接读取缓冲区的第一个字符(无论这个字符是什么)


故,上例中,向缓冲区中输入:123\n

1、语句scanf("%d",&a); 读取走了123,赋给变量a;
(缓冲区变化:123\n → \n)
2、语句scanf("%c",&c);读取走了\n**,赋给变量c;
(缓冲区变化:\n → 空白)


解决方法1:

利用函数getchar( )吃掉回车:在scanf后接一个getchar( );

#include <stdio.h>
int main()
{
    int a;
    char c;
    scanf("%d",&a);
    getchar();/*吃掉回车*/
    scanf("%c",&c);
    printf("%d %c",a,c); 
}

解决方法2:

利用函数fflush( )清除缓冲区:如fflush(stdin);

#include <stdio.h>
int main()
{
    int a;
    char c;
    scanf("%d",&a);
    fflush(stdin);/*清除输入缓冲区*/
    scanf("%c",&c);
    printf("%d %c",a,c); 
}

注意 注意 注意 :

有同学可能用的是新版的vs,可能不支持该方法2;可以试一下替换成**rewind(stdin)**函数;

或者可以直接一次性读取两个数据scanf("%d%*c", &c);——注意星号*哈!
这句话的意思是就是说:读取一个整数后,丢弃紧跟在整数后边的一个字符(也就是我们多输入的“回车符”);


问题二:“为啥在我输入数据和回车之后程序没有反应?”——在函数scanf( )的格式字符串中加入\n的问题:

例如:

#include <stdio.h>
int main()
{
	int a;
	scanf("%d\n",&a);/*注意%d后的\n*/
	printf("%d",a);
}

这种情况下,按照“整型数字 回车”的格式读取,读到回车之后,由于缓冲区空白,程序停滞。程序停滞,光标闪烁,等待键盘输入。所以当你输入一个整数和回车后,a的值不会立即打印,要等再接收到一个非空白符(即非空格、回车、制表符等)的输入之后,该scanf语句才结束,接着才输出。

如图:
在这里插入图片描述

解释:当输入:123 程序框中换行但并不打印; 继续输入:456 此时换行,并且输出了刚才键入的123;

总之,在使用函数scanf( )时,应该心中有一个缓冲区,合理利用相关函数来解决键盘缓冲区残余信息的问题;同时,理解读取格式,以便搞清楚何时函数scanf()结束;啊啊啊加油加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值