VS2017下的getch函数

在C语言中, _getch函数是非缓冲读数据的,当我们按下一个键之后,程序立马就会响应,不管按下的是否为回车键。应当注意的是,_getch函数不是标准库函数,想要使用该函数,应当包含conio.h头文件。

_getch函数是不带回显的,也就是说,当我们输入了一个字符,该字符会被程序接收,但是不会在显示器中显示出来。同时,_getch函数并不从缓冲区读取字符。因为该特性,_getch函数经常用作游戏中接受用户按键的函数。

 

但是,在使用该函数时,发现了问题:

在Debug版本下,第一次使用_getch函数后,下一次再使用_getch函数,会自动接受一个莫名其妙的\0。但是Release版本下不会有这个情况:

 

 

(在两个版本下,都只按了一下键盘,但是区别很明显)

 

所以怀疑(因为并没有直接的证据证明)是:在vs环境debug版本下使用_getch函数,实际上是从缓冲区读取字符(Release和Debug版本分别从两个dll里找函数,这就使得Release版本和Debug版本的函数一般都不同),而使用_getch函数时,该函数在读取后又向缓冲区放入了一个’\0’,这就导致了在下一次使用_getch函数时,_getch函数直接从缓冲区读到了’\0’。导致看起来程序并没有在第二次使用_getch函数时等待用户输入。

 

解决方法:

最基础的解决方法:

因为我们已经知道了出现上文所述问题的原因(暂且认为上面的假设成立),所以我们在第一次使用_getch()后再使用一次_getch()将缓冲区的字符’\0’取出来抛掉。那么在下一次使用_getch()时缓冲区中就没有字符可以接收,程序就会停在_getch处等待用户输入。

在这里可能有读者会提出另外一个问题,为什么不使用rewind(stdin)来清理缓冲区? 本人在这里也使用rewind(stdin)测试过,但是并没有起到作用,所以我怀疑在vs的Debug版本下,_getch()函数使用的是另外的缓冲区?

 

进阶的解决方法:

这种方法是自己编写一个getCh函数,在要使用_getch函数时可用getCh来代替两次连续两次使用_getch函数。

在这里可能又有读者要提问了:为什么你定义的getCh函数的返回类型是int型的?

这是因为getch函数的原型就是int型的函数,在使用后返回的是用户所输入的字符对应的ASCII码值。

 

(_getch函数原型)

当然,要是你愿意写成char型也可以,程序在运行时会自己转换类型处理。

 

比较严谨的解决方法:

因为在前两种解决方法中,我们只是针对了Debug版本做出了解决方法,因为在vs的Release版本下,使用_getch函数并不会出现开篇的问题,那么如果采用了前两种解决方法写的代码,又执行了Release版本,就会导致程序在运行时,用户输入一个字符后,还需要在按任意键才会向下继续执行,就会使用户体验极差。所以才会提到这种比较严谨的解决方法。即在Release版本下没有编译条件编译里的内容,这样就不会执行其中的内容。

 

当然,本文只是提供了解决问题的思路,观点不一定正确,还望各位前辈斧正。

 

PS:本文于2018年12月8日编写。本人第一次在优快云发文,还请各位前辈多多指正。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值