getch()和_getch()之间的差异

时间:2012-08-17 15:47:49

标签: c++ c

  

可能重复:
  getch is deprecated

正如标题所说,这两种方法之间的差异是什么?我很新,所以我对它们的使用感到困惑......

2 个答案:

答案 0 :(得分:3)

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

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

首先,getch未在标准标头中声明,因此不必以 1 开头更改名称。 其次,如果他们确实需要更改名称,_getch无论如何都是正确的 - 为实现保留的名称以下划线开头(他们得到了很多权利),后跟另一个下划线或者大写字母(他们错了)。换句话说,如果他们要更改名称,则应该是__getch_Getch,但至少就标准问题而言,_getch同样糟糕如getch

就他们之间的选择而言:我只是使用getch并完成它。使用_getch实际上使你的代码(略微)可移植 - 在大多数Unixesque系统上做同样的事情,你使用curses,其中包括一个函数(大多数)相同的工作 - 它的名字是{ {1}}。因此,如果您移植了代码,则需要更改包含的标题,但名称getch是少数几个实际可以继续使用的标题之一。如果你正在做很多交互式I / O,你可能不得不重写其他很多代码。


1 嗯,反正不应该。回到16位时间,微软的链接器有一个小问题,你必须传递一个额外的开关(getch)或你定义的名称之间的任何重复,以及在您链接的库将导致错误。所以,那时你必须传递一个额外的开关来获取代码链接,如果它使用与库中的任何相同的名称,而不仅仅是标准名称。这虽然是古老的历史。

答案 1 :(得分:3)

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

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

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

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

对于新代码,我认为使用新名称(使用下划线并且没有在oldnames.lib中链接)可能稍微好一点。微软不推荐使用旧的名称,而其他所有相同的名称都可能会缩小规模。如果您最终将代码移植到POSIX系统或将POSIX代码移植到Windows,那么您将更有可能收到可能需要注意的区域的警报。这些函数看起来很像POSIX版本,但它们可能需要以稍微不同的方式使用 - 特别是在错误处理方面。

或者您可以尝试像PDCurses这样的库,或使用您自己的包装器来提供可移植性,具体取决于您可能值多少钱。或者,如果你真的想在Windows上实现POSIX可移植性,那么Cygwin可能是一个选择(Unix的服务还在吗?)。

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

    Windows上的
  • getch()不会回显字符,在输入之前总是阻塞,需要多次调用才能读取某些键,并且不能返回错误。这些行为与POSIX不同。
  • Windows上的
  • ungetch()返回传入的字符或错误时EOF。在POSIX上,它返回OKERR