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

本文详细讲述了在Visual Studio 2019之后如何解决scanf读取键盘输入时的缓冲区问题,介绍了rewind(stdin)替代fflush(stdin)的方法,以及使用scanf(“%*[^ ]%c”)的技巧。同时讨论了为何这些方法失效以及可能导致的栈溢出问题,并给出了正确处理字符输入的建议。
摘要由CSDN通过智能技术生成

解决关于VS2019无法使用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.1、使用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’。

2.2 、scanf("%c")
scanf("%*c")这个函数,它的功能是
清除缓冲区的最后一个字符*。
将rewind函数改为scanf("%*c"),代码如下。

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

执行结果正确,且程序正常结束。
————————————————

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值