偶尔读取字符串失败(gets()函数等),与预期不一致

说一个比较有意思的bug,我自己之前也许是上课没咋认真不知道怎么处理这个问题,也是最近才明白底层问题

代码可在devcpp运行,linux亦可

相信一定有童鞋在学校写作业的时候遇到一个问题吧,有时候使用gets()函数会出问题(莫名其妙的,有时候没问题,有时候又又有问题)

接下来用一段简单的代码模拟一下这个情景

#include<stdio.h>
#include<string.h>
int main()
{
	int a=0,b=0;
	char c[20];
	scanf("%d",&a);
	scanf("%d",&b);
	//scanf("%s",c);//%s这种输入方式不会导致无法正常读取,或许是,有特殊的处理吧
                    //(如果缓冲区遗留空格,'\n'(输入同理) )
    //getchar();//专门拿来清空缓冲区的函数,在需要读取字符前的函数
                //使用这个函数准没有错(这是我的观点不代表我的立场)
	fgets(c,10,stdin);//fgets()函数跟gets()函数是差不多的,我用fgets()函数
                      //仅仅是因为我linux的编译器不支持gets()函数(不安全,所以被禁用)
    printf("%d %d %s\n",a,b,c);
	return 0;
}

输入1回车2回车(此时可能你还想输入一个字符串),but直接就显示结果,小小的脑袋大大的问号是吧

(熟悉吧,哈哈哈)

//当然,如果使用另一种输入方式是没有问题的 1 2 hhh 因为读到空格gets()函数是不会退出的

问题出在输入缓冲区残留了'\n'字符,所以调用gets函数的时候首先读到的就是'\n'字符,而gets()函数读到'\n'就退出,所以也就不能输入字符串了,解决方式就是加一个getchar()函读取空缓冲区剩下的一个字符(注意我的措辞,是一个)

到这里就已经明白为什么gets()函数会"偶尔"出问题了


接下来,深入一点讨论缓冲区与getchar()函数

(1)首先说一说这个残留是怎么来的

scanf("%d",&a);这行代码只会读取一个整型数据,剩下的都会遗留在缓冲区也就是说输入110abc 那么abc就会残留在缓冲区

(2)缓冲区只会保存最近一次的输入,也就是说  1\n1\n 这样的输入(第一个\n之后就是第二次输入了,因为 \n标志着第一次输入的结束,这不难理解),缓冲区只会残留一个'\n'字符

但是如果说输入 1\n1  123\n  这个时候缓冲区残留的数据就不仅仅是一个'\n'了,还有多余的空格以及123

这有什么问题呢,这个时候一个getchar()函数可能就解决不了问题了

比如(用我代码实验的友友,请先启用我注释掉的getchar()函数 ) 输入 1\n2\n空格\n 这个时候getchar读走的就是空格,而\n还在缓冲区,也就不能正常执行了

自己实验一下就知道了,就不一一细细讨论了(熄灯了,不想干了)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值