zoukankan      html  css  js  c++  java
  • 为什么连续的scanf会被跳过或不执行

    前言-

    这几天再尝试学一下C语言,对着RUNOOB.com的教程一通操作,还是一脸雾水。问题倒是积累了不少。

    正文-

    问题一:“为啥我的第二个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已经读入了值‘ ’,即ASCII码为10的字符——换行符;
    如调试图:


    a = 123, c= 10'
'

    实际上:

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

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

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

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

    解决方法:
    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( )的格式字符串中加入 的问题:

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

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

    如图:


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

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


    原文链接:https://blog.csdn.net/HNAKXR/java/article/details/81047391

  • 相关阅读:
    SharePoint 2013 文档库中PPT转换PDF
    Linux线程-互斥锁pthread_mutex_t
    利用Python,四步掌握机器学习
    linux 文件夹权限及umask
    Android.mk入门(一)
    《Linux性能及调优指南》----1.1 Linux进程管理
    从进程到线程
    从程序到进程
    Android源码解析系列
    嵌入式工程师必读100本专业书籍
  • 原文地址:https://www.cnblogs.com/YFEYI/p/12870671.html
Copyright © 2011-2022 走看看