C++ getch() 和 _getch() 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12008979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:45:40  来源:igfitidea点击:

Differences between getch() and _getch()

c++c

提问by ducnh

Possible Duplicate:
getch is deprecated

可能重复:
不推荐使用 getch

As title says, what are diffrences between those two methods? I'm new so I'm confused about the usage of them...

正如标题所说,这两种方法有什么区别?我是新手,所以我对它们的用法感到困惑......

回答by Jerry Coffin

At least in the implementations of which I'm aware, there's no difference between the functions themselves. In fact, they're generally just two different names for exactly the same function.

至少在我知道的实现中,函数本身没有区别。事实上,它们通常只是完全相同功能的两个不同名称。

As to the reason for having two names: there really isn't a very good one. Somebody at Microsoft apparently didn't read the requirements of the standard very carefully, and made some rather...poor decisions based on misunderstanding it.

至于有两个名字的原因:真的没有一个很好的。微软的某些人显然没有非常仔细地阅读标准的要求,并基于误解做出了一些相当......糟糕的决定。

First, getchisn't declared in a standard header, so changing the name isn't really necessary to start with1. Second, if they did need to change the name, _getchisn't right anyway -- the names reserved for the implementation start with an underscore (they got that much right) followed by either another underscore or a capital letter (which they got wrong). In other words, if they were going to change the name, it should have been either __getch, or _Getch, but at least as far as the standard cares, _getchis just as bad as plain getch.

首先,getch不是在标准头文件中声明的,因此从1开始更改名称并不是真正必要的。其次,如果他们确实需要更改名称,_getch无论如何都是不对的 - 为实现保留的名称以下划线开头(他们说得对),然后是另一个下划线或大写字母(他们弄错了) . 换句话说,如果他们要更改名称,则应该是__getch, 或_Getch,但至少就标准而言,_getch它与普通 一样糟糕getch

As far as choosing between them goes: I'd just use getchand be done with it. Using _getchactually makes your code (marginally) less portable -- to do the same thing on most Unixesque systems, you use curses, which includes a function to do (mostly) the same job -- and its name is getch. As such, if you ever port your code, you'll need to change the header(s) you include, but the name getchis one of the few that will actually continue to work. If you're doing much interactive I/O, you'll probably have to rewrite quite a bit of other code though.

至于在它们之间进行选择:我只是使用getch并完成它。使用_getch实际上使您的代码(略微)降低了可移植性——要在大多数 Unixesque 系统上做同样的事情,您可以使用 Curses,它包括一个执行(大部分)相同工作的函数——它的名字是getch. 因此,如果您曾经移植过代码,则需要更改包含的标头,但该名称getch是少数几个实际上可以继续工作的标头之一。如果您要进行大量交互式 I/O,则可能需要重写相当多的其他代码。



1Well, it shouldn't be anyway. Back in the 16-bit days, Microsoft's linkerhad a little problem that you had to pass it an extra switch (/noe) or any duplicate between names you defined, and names defined in a library you were linking would result in an error. So, back then you had to pass an extra switch to get code to link if it used the same name as anythingin the library, not just a standard name. That's pretty much ancient history though.

1好吧,无论如何都不应该。回到 16 位时代,Microsoft 的链接器有一个小问题,您必须向它传递一个额外的开关 ( /noe) 或您定义的名称之间的任何重复项,并且在您链接的库中定义的名称会导致错误。因此,那时您必须传递一个额外的开关来获取要链接的代码,如果它使用与库中的任何名称相同的名称,而不仅仅是标准名称。但这几乎是古老的历史。

回答by Michael Burr

Very old implementations of Microsoft's C compilers provided functions that used names that were the same as those in the POSIX/UNIX world and/or infringed on the user's namespace. Note that some of these were 'infringements' were probably done from before standardization took place (in the MS-DOS days).

Microsoft 的 C 编译器的非常旧的实现提供的函数使用的名称与 POSIX/UNIX 世界中的名称相同和/或侵犯了用户的命名空间。请注意,其中一些“侵权”可能是在标准化发生之前(在 MS-DOS 时代)完成的。

At some point a long time ago Microsoft decided to move these names to a a set of names that was reserved for the compiler implementation. They did this for many names in the library, even if they might not have had to, strictly speaking. It appears that they did this pretty much for all library names that weren't standard C/C++. Note that this doesn't apply to names in the SDK - that set of headers and libraries is outside the compiler implementation domain, even if the SDK is distributed with the compiler.

很久以前,Microsoft 决定将这些名称移到一组为编译器实现保留的名称中。他们对图书馆中的许多名字都这样做了,即使严格来说他们可能没有必要这样做。看起来他们几乎对所有不是标准 C/C++ 的库名称都这样做了。请注意,这不适用于 SDK 中的名称 - 即使 SDK 与编译器一起分发,该组标头和库也在编译器实现域之外。

For compatibility with programs written with the old names (the ones without the underscore) Microsoft provides a library, oldnames.lib, that implements aliases which link the old names (such as getch) to the new names (_getch). Both names refer to the exact same code. So as far as making things work, you can use either name (though you may need to set up your project to link in oldnames.lib).

为了与使用旧名称(没有下划线的名称)编写的程序兼容,Microsoft 提供了一个库 oldnames.lib,它实现了将旧名称(例如getch)链接到新名称 ( _getch) 的别名。这两个名称指代完全相同的代码。因此,就工作而言,您可以使用任一名称(尽管您可能需要将项目设置为链接到oldnames.lib)。

If you have old Windows code that uses the old names, I think it's probably best to just link in oldnames.liband be done.

如果您有使用旧名称的旧 Windows 代码,我认为最好只是链接oldnames.lib并完成。

For new code, I think using the new names (with the underscore and without linking in oldnames.lib) might be marginally better. The old names are deprecated by Microsoft, and all else being equal that should probably tip the scales. And if you end up porting your code to a POSIX system or porting POSIX code to Windows, there's a better chance you'll be alerted to areas that may need attention. The functions may look and mostly act like the POSIX versions, but they may need to be used in slightly different ways - particularly in error handling.

对于新代码,我认为使用新名称(带有下划线且在 oldnames.lib 中没有链接)可能会好一些。旧名称已被 Microsoft 弃用,其他条件相同的情况下,可能会影响天平。而且,如果您最终将代码移植到 POSIX 系统或将 POSIX 代码移植到 Windows,您将更有可能收到可能需要注意的区域的警报。这些函数可能看起来和大部分行为都类似于 POSIX 版本,但它们可能需要以略有不同的方式使用 - 特别是在错误处理方面。

Or you could try a library like PDCurses or use your own wrappers to provide portability, depending on how much that might be worth to you. Or if you really want POSIX portability on Windows, Cygwin might be an option (is Services for Unix still around?).

或者您可以尝试像 PDCurses 这样的库或使用您自己的包装器来提供可移植性,这取决于它对您的价值。或者,如果您真的希望 Windows 上的 POSIX 可移植性,Cygwin 可能是一个选择(Unix 服务是否仍然存在?)。

Some examples of subtle differences between MSVC and POSIX functions which have the same/similar names:

具有相同/相似名称的 MSVC 和 POSIX 函数之间细微差异的一些示例:

  • getch()on Windows doesn't ever echo the character, always blocks until there is input, requires multiple calls to read some keys, and cannot return an error. Those behaviors differ than on POSIX.
  • ungetch()on Windows returns the character passed in or EOFon error. On POSIX it returns either OKor ERR.
  • getch()在 Windows 上永远不会回显字符,总是阻塞直到有输入,需要多次调用才能读取某些键,并且不能返回错误。这些行为与 POSIX 不同。
  • ungetch()在 Windows 上返回传入或EOF出错的字符。在 POSIX 上,它返回OKERR