解决关于VS2017无法使用flush(stdin)的问题

以前,fflush函数是用来对缓冲区进行操作的。fflush(stdin)用于清空缓区,fflush(stdout)强制输出当前缓冲区中的内容。但是自从VS2015之后,fflush(stdin)就不能用了(使用时不会报错,但是没有清空缓冲区的效果)。
我们在进行从键盘中输入数据时,有时不得不清空缓冲区,比如下面这段代码。

char a,b;
scanf("%c",&a);
scanf(%c",&b);
printf("%c %c",a,b);

当我输入1 2时,正常情况应该输出1 2,但实际的输出结果却并非如此。
运行情况
当我输入完1,按完回车准备继续输入2时,发现程序输出了1,然后又输出了一个换行,之后程序就执行结束了。这是因为当你按回车的时候,程序以为这是你输入的第二个字符,这就解释了为什么程序输出一个1后,又输出了一个换行就结束了。
要解决这个问题,以前是可以这样修改代码的。

char a,b;
scanf("%c",&a);
fflush(stdin);
scanf(%c",&b);
printf("%c %c",a,b);

但是前面也说过,VS2015之后这个方法就失效了(VC依然可以使用此方法),使用新版的VS,有两种方法来解决这个问题。
1.把fflush(stdin)替换成rewind(stdin)

char a,b;
scanf("%c",&a);
rewind(stdin);
scanf("%c",&b);
printf("%c %c",a,b);

在这里插入图片描述

2.使用scanf(“%*[^\n]%*c”)
关于这个函数,我从网上搜了一大堆对它的解释,但还是没有特别理解。它好像是读取字符串,遇到换行符\n时读取结束,我用如下代码进行测试。

char a,b;
scanf("%[^\n]%*c", &a);
scanf("%[^\n]%*c", &b);
printf("%c %c",a,b);

测试结果如图
测试结果
程序输出结果是正确的,但是却引发了异常中断,中断信息为:Run-Time Check Failure #2 - Stack around the variable ‘a’ was corrupted.从网上搜了一下,这是因为栈被破坏了。最常引起这种错误的情形是对数组进行操作时,比如说定义一个 int num[10]这样的数组,当你想要改变num[10]的值时,就会引发异常中断,这是因为数组下表是从0开始的,数组num的10个元素分别是num[0]~num[9],根本没有num[10]这个元素。前面说过,scanf(“%*[^\n]%*c”,&a)是用来读取一行字符串存储到&a这个地址,注意是字符串,字符串的末尾要有一个’\0’,这样当你输入一个字符之后按回车,实际上要存储两个字符,一个是你输入的字符,另一个是自动添加的’\0’,而我们对a的定义是char a,也就是说只能访问&a的地址,而不能访问&a + 1的地址,如果你想要强行访问,就会引发异常中断。下面的这段代码用来验证我的上述猜想。

		char str[10];
		scanf("%[^\n]%*c", str);
		scanf("%[^\n]%*c", str+2);

设断点进行调试,发现str[1]和str[3]都是’\0’。
在这里插入图片描述
然后我又从网上搜索,找到了scanf("%*c")这个函数,它的功能是清除缓冲区的最后一个字符。因此可以把第一种法案中的rewind函数改为scanf("%*c"),代码如下。

char a,b;
scanf("%c",&a);
scanf("%*c");
scanf("%c",&b);
printf("%c %c",a,b);

运行演示
执行结果正确,且程序正常结束。

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值