等效于 Mac/Linux 崩溃的 Windows getch()
Posted
技术标签:
【中文标题】等效于 Mac/Linux 崩溃的 Windows getch()【英文标题】:Equivalent to Windows getch() for Mac/Linux crashes 【发布时间】:2010-09-21 00:03:03 【问题描述】:我正在使用getch()
,我的应用程序立即崩溃。包括在做的时候:
int main()
getch();
我找不到链接,但据推测问题是它需要关闭缓冲或类似这些奇怪的东西,我仍然希望 cout
与跨平台代码一起工作。
有人告诉我使用std::cin.get()
,但我希望应用程序在按下某个键时退出,而不是在用户输入字母或数字然后按回车键退出时退出。
这有什么功能吗?代码必须在 Mac(我的操作系统)和 Windows 下工作。
链接/编译不是issue;我在 XCode 中包含 <curses.h>
并与 -lcurses
链接,而 Windows 使用 <conio.h>
。
【问题讨论】:
请注意,'cout' 是一个 C++ 结构。尽管到目前为止的答案主要是针对 C 的,但它们也适用于 C++。并且 std::cin.get() 将被卡在等待一行终端输入 - 'Hit Enter' 综合症 - 就像 getchar() 或任何其他标准 I/O 函数一样。 我遇到了类似的问题,这个Link 可能会有所帮助。 【参考方案1】:您是否查看过<curses.h>
以了解getch()
函数的作用?
提示:OSX 和 Linux 与 Windows 不同。
具体来说,作为<curses.h>
中的宏,我们发现:
#define getch() wgetch(stdscr)
现在,在您的系统上,curses 库中出现了一个实际函数 getch()
,但它希望设置 stdscr
,这是由 curses 初始化函数(initscr()
和亲戚),这显然不是由您的代码完成的。因此,您的代码通过在正确初始化完成之前调用 curses 例程来调用未定义的行为,从而导致崩溃。
(来自 dmckee 的好提示 - 它有助于将链接线从 acidzombie24 中取出,这很重要。)
为了达到可以读取单个按键并干净地终止程序的程度,您必须在 Unix(OSX、Linux)上做大量工作。您必须捕获终端的初始状态,安排 atexit()
函数 - 或一些类似的机制 - 来恢复终端的状态,将终端从熟模式更改为原始模式,然后调用一个函数来读取字符(可能只是read(0, &c, 1)
),然后退出。可能还有其他方法可以做到这一点 - 但它肯定会涉及一些设置和拆卸操作。
Mark Rochkind 的《Advanced Unix Programming, 2nd Edn》是一本可能有帮助的书;它涵盖了所需级别的终端处理。或者,您可以正确使用<curses.h>
- 这比自己动手解决方案更简单,而且可能更可靠。
【讨论】:
【参考方案2】:你还没有展示过
#include <stdio.h>
或
#include <curses.h>
或类似的行。您确定要链接到 包含 getch()
的库吗?
【讨论】:
链接/编译不是问题,我在 xcode 中包含了 curses 和 do -lcurses。窗口使用 conio.h【参考方案3】:以 cin.get() 函数为例:
#include <iostream>
using namespace std;
int main()
char input = cin.get();
cout << "You Pressed: " << input;
然后程序会等待你按下一个键。
一旦你有了,你按下的键就会被打印到屏幕上。
【讨论】:
或者只使用getchar()函数【参考方案4】:getch
函数在类 Unix 系统上不可用,但您可以通过带有 system
函数的编译器将其替换为控制台命令。
用法:
在 Windows 中,您可以使用 system("pause");
在类 Unix 系统(如 OSX)中,您可以使用 system("read -n1 -p ' ' key");
注意:system
在<stdlib.h>
中声明。
【讨论】:
这将暂停您的程序,直到用户按下一个键 - 任意键- 就像在getch();
中一样
请不要建议system()
来电。这是一种糟糕的编程习惯,并且有不好的副作用。以上是关于等效于 Mac/Linux 崩溃的 Windows getch()的主要内容,如果未能解决你的问题,请参考以下文章
平台详细信息捕获 API/工具——Windows 错误报告等效项