解释:为什么scanf被跳过或不执行

解释:为什么scanf被跳过或不执行作为初学者(对!就是我!一直排这个错!快被整毁了!),可能会经常莫名遇到“为啥我的第二个scanf()函数自动跳过,不等待我输入就自己执行了?”的问题,或者会遇到“为啥在我输入数据和回车之后程序没有反应?”,以下是浅薄的解释:问题一:“为啥我的第二个scanf()函数自动跳过,不等待我输入就自己执行了?”一个很简单的例子:#include<stdio.h&gt…

作为初学者(对!就是我!一直排这个错!快被整毁了!),可能会经常莫名遇到*“为啥我的第二个scanf()函数自动跳过,不等待我输入就自己执行了?”的问题,或者会遇到“为啥在我输入数据和回车之后程序没有反应?”*,以下是浅薄的解释:

问题一:“为啥我的第二个scanf( )函数自动跳过,不等待我输入就自己执行了?”

一个很简单的例子:

#include <stdio.h>
/*试图两次利用scanf()函数,先后读取整型变量a和字符型变量c*/
int main()
{ 
   
	int a;
	char c;
	scanf("%d",&a);
	scanf("%c",&c);
	printf("%d %c",a,c); 
}
解析:当我们输入:123 ↙
会发现程序会“直接”打印整数123,好像并没有给我们留下时间和空间输入字符型变量c的值(一开始我也一脸懵B??).
但是,经过调试(啊,万能的调试!),我们可以发现,其实整型变量c已经读入了值‘\n’,即ASCII码为10的字符——换行符;
如调试图:

a = 123, c= 10'\n'


实际上:

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

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


值得注意的是,scanf()中格式字符串里:

-对于参数%d:忽略缓冲区开头的空白符(空格、回车、制表符等)(无论有几个);
-对于参数 %c:直接读取缓冲区的第一个字符(无论这个字符是什么);


故,上例中:

1º 向缓冲区中输入:123\n
2º 语句scanf(“%d”,&a); 读取走了123,赋给变量a
(缓冲区变化:123\n → \n)
3º 语句scanf(“%c”,&c);读取走了**\n,赋给变量c**;
(缓冲区变化:\n → 空白)

**注意:**程序从缓冲区读取完(即完成scanf语句的格式串的匹配)就是scanf语句结束了,语句结束了就不管缓冲区空不空了,自然程序会执行下一条的printf语句


解决方法:

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);
}

这种情况下,即“如果scanf的格式匹配串末尾有**\n的话”,程序会不断地连续忽略空白符(也就是说缓冲区的空白符凭空被读取掉而又忽略走了),直到有非空白符出现在缓冲区;在这里即使我们不断输入“回车回车回车…”,也会被一直被程序忽略,缓冲区一直是空白,一直光标闪烁,等待键盘输入,造成阻塞的感觉。
故,当你输入一个整数和回车后,a的值
不会立即打印**,要等再接收到一个非空白符(即非空格、回车、制表符等)的输入之后,该scanf语句才结束,接着才输出。

如图:
123 456 123

解释:当输入:123↙ 程序框中换行但并不打印;(即使再输入几个↙ ↙ ↙ 也会是只在程序框中换行)
继续输入:456↙ 此时换行,并且输出了刚才键入的123;

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/36102.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注