在Linux上使用kbhit()和getch()

在Windows上,我有以下代码来查找input而不中断循环:

#include <conio.h> #include <Windows.h> #include <iostream> int main() { while (true) { if (_kbhit()) { if (_getch() == 'g') { std::cout << "You pressed G" << std::endl; } } Sleep(500); std::cout << "Running" << std::endl; } } 

但是,看到没有conio.h ,在Linux上实现这个同样的事情最简单的方法是什么?

上面引用的ncurses howto可以是有帮助的。 这里是一个例子说明如何使用ncurses像conio的例子:

 #include <ncurses.h> int main() { initscr(); cbreak(); noecho(); scrollok(stdscr, TRUE); nodelay(stdscr, TRUE); while (true) { if (getch() == 'g') { printw("You pressed G\n"); } napms(500); printw("Running\n"); } } 

请注意,使用ncurses,不使用iostream头。 这是因为混合stdio和ncurses可能会有意想不到的结果。

ncurses,顺便说一句,定义TRUEFALSE 。 正确configuration的ncurses将使用与ncurses'bool相同的数据types作为用于configurationncurses的C ++编译器。

如果您的linux没有支持kbhit() conio.h ,您可以在这里查看Morgan Mattews的代码,以兼容任何POSIX兼容系统的方式提供kbhit()function。

由于诀窍在termios级别禁用了缓冲,因此它也应该解决getchar()问题,如此处所示。

虽然使用ncurses在function上等同于Turbo C“conio.h”API,但更完整的解决scheme是使用conio实现,可以在这里find 。

您可以在程序中下载并使用它,以便在Linux上完全实现conio接口。 (或者OSX)。由Ron Burkey写。

基于Christophe的答案是一个紧凑的解决scheme

 #include <sys/ioctl.h> #include <termios.h> bool kbhit() { termios term; tcgetattr(0, &term); termios term2 = term; term2.c_lflag &= ~ICANON; tcsetattr(0, TCSANOW, &term2); int byteswaiting; ioctl(0, FIONREAD, &byteswaiting); tcsetattr(0, TCSANOW, &term); return byteswaiting > 0; } 

与这个答案不同的是,在程序退出之后,这不会使terminal处于奇怪的状态。 但是,它仍然留在input缓冲区中的字符,所以被按下的键将不受欢迎地出现在下一个提示行上。

解决这个问题的一个不同的解决scheme是

 void enable_raw_mode() { termios term; tcgetattr(0, &term); term.c_lflag &= ~(ICANON | ECHO); // Disable echo as well tcsetattr(0, TCSANOW, &term); } void disable_raw_mode() { termios term; tcgetattr(0, &term); term.c_lflag |= ICANON | ECHO; tcsetattr(0, TCSANOW, &term); } bool kbhit() { int byteswaiting; ioctl(0, FIONREAD, &byteswaiting); return byteswaiting > 0; } 

用法如下

 enable_raw_mode(); // ... if (kbhit()) ... // ... disable_raw_mode(); tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt 

现在,在第一行和最后一行的执行之间键入的任何字符都不会显示在terminal中。 但是,如果用Ctrl + C退出,terminal处于奇怪的状态。 (叹)