我有一个函数getch(),其工作方式与Unix(Mac OSX?)getchar()或Windows _getch()的工作方式大致相同,只是它不会等待用户在返回值之前按Enter键。我想使用它,因为它避免了必须使用system()来实时输入。 (我必须做一些类似系统(“stty raw”)的事情,用上面提到的函数来做相同的事情,无论出于什么原因,stty raw真的搞砸了我的终端的缩进。)这是代码:
#include <termios.h>
char getch() {
char buf = 0;
struct termios old = {0};
if (tcgetattr(0, &old) < 0)
perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSANOW, &old) < 0)
perror("tcsetattr ICANON");
if (read(0, &buf, 1) < 0)
perror ("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if (tcsetattr(0, TCSADRAIN, &old) < 0)
perror ("tcsetattr ~ICANON");
return (buf);
}
int main() {
//std::thread InputThread(GetInput);
int c = 0;
while(c != 127) { // Delete key is 127
c = getch();
std::cout << "Input: " << c << "\n" << endl;
}
std::cout << "Broke!" << endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
Quit();
//InputThread.detach();
return 0;
}
它的工作方式与您预期的一样。您输入一个键,然后将其打印回给您。如果按删除,程序将退出。然而,奇怪的是,如果你按下向上箭头,你会得到如下所示的输出:
Input: 27
Input: 91
Input: 65
功能键和其他箭头键的输出看起来相似。 (我会注意到,如果我使用getchar(),也会发生这种情况)
std :: cout只被调用一次。那为什么要打印三次呢?我希望我的程序检测用户按F1,然后退出。但如果我的程序以这种方式运行,我不知道如何做到这一点。
任何帮助深表感谢。我的平台是Mac OSX,如果它是相关的。
你正在读输入一个字符,一次一个字节;然而,按下单个键可能不一定产生一个字符。按下时,向上光标键生成三个字符ESC [ A
,这是光标向上键in the ANSI/VT100 series of terminal emulators的常见映射。
使用非英语键盘映射时,即使字母本身也会生成多个字符。例如,在西里尔语键盘上按下西里尔字母“а”会读取两个字符:208,176。
请注意,“ESC”键本身读取单个ESC字符。在阅读ESC
之后,没有任何东西可以表明这是一个独立的“Esc”按键,还是许多可能代表特殊键的多字符序列中的第一个。
终端库,如curses,通常采用从终端读取ESC后启动短暂超时的方法。如果没有其他角色到达,他们就会认为ESC是自己按下的。如果立即读取更多字符,它们将尝试查找读取字符序列所代表的特殊键。
在自己阅读终端时,由您完成所有这些工作。没有别的办法可以帮到你。