关于C语言中的scanf()与缓冲区残留问题的解析(缓冲区残留导致char类型输出“错误”问题)

本文详细解析了C语言中常见的输入问题,特别是当从标准输入读取不同类型的变量时遇到的char类型“跳过”现象。文章通过示例代码解释了输入缓冲区的工作原理,以及如何使用getchar()或fflush(stdin)来清除残留的换行符,确保后续输入正确读取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个常见的问题

   #include <stdio.h>
    int main()
    {
        int    a;
        char   b;
        float  c;
        printf("Please input an integer:");    
        scanf("%d", &a);
        printf("integer:%d\n", a);
        printf("Please input a character:");    
        scanf("%c", &b);
        printf("character:%c\n", b);
        printf("Please input a float number:");    
        scanf("%f", &c);
        printf("float:%f\n", c); 
        return 0;
    }

问题:为什么运行这个程序得不到下面希望得到的运行结果?
来自https://www.icourse163.org/learn/HIT-69005?tid=1205977203#/learn/content?type=detail&id=1210349489&cid=1212358505
问题来源

我的想法是

该代码段运行时出现的问题是char类型变量b在输入时像是被“跳过”,直接输出结果,且输出内容直观上是一个“换行”。
运行截图

按我的理解,是因为在第一条scanf语句scanf("%d",&a); 执行结束时用户按下回车键的时候,在产生回车的同时产生了一个换行符,比如输入9再键入回车,此时输入缓冲区中存的(以ASCII码存储)是39H 0DH 0AH(分别对应“9”,“回车”,“换行”) ,然后读取完39H和0DH后,不会马上清空换行符0AH,而是根据下面的第二条输入语句scanf输入的类型判断,有以下两种情况

1)如果第二次输入的是字符类型(char类型,控制格式%c)或字符串类型(控制格式%s),(本次讨论问题中d第二次输入数据类型为char类型),则将缓冲区中残余的0AH当作%c或%s的输入,故在屏幕中显示好像是“跳过”了该输入步骤,并且产生“换行”效果。
解决办法(亲测有效):
[1]在第一个scanf后,第二个scanf前加入getchar();语句,读取掉输入缓冲区残留的回车键;
[2]在第一个scanf后,第二个scanf前加入fflush(stdin);语句,清空整个输入缓冲区。
PS.初学者不建议马上太深入去看这两个函数,先弄懂主要用法就好,不然容易绕进去(๑•̀ㅂ•́)و✧

2)但是如果第二次输入的不是%c和%s这两种类型而是一些像是%d,%f之类的,因为这些类型的变量无法读取非”数“类型的数据,所以会自动抛弃缓冲区中残余的换行符0AH,所以这样的代码不会出错:

    #include <stdio.h>
    int main() {
        int    a;
        char   b;
        float  c;
        
        printf("Please input a character:");
        scanf("%c", &b);
        printf("character:%c\n", b);
    
	    printf("Please input an integer:");
	    scanf("%d", &a);
	    printf("integer:%d\n", a);
	     
	    printf("Please input a float number:");
	    scanf("%f", &c);
	    printf("float:%f\n", c);
	    
	    return 0;
	    
    }

运行截图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值