在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,顺便说一句,定义TRUE
和FALSE
。 正确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将处于奇怪的状态。 (叹)