【发布时间】:2016-03-16 15:55:36
【问题描述】:
我正在尝试在 OSX 终端或 xterm 上捕获 ESC 键(ASCII 27),使用 kbhit 来区分真正的 Escape 与箭头键:
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
static struct termios newt;
static struct termios oldt;
static void kb_fini(void)
{
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
}
void kb_init(void)
{
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= (tcflag_t)~(ICANON | ECHO | ISIG);
newt.c_cc[VMIN] = 1;
newt.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
atexit(kb_fini);
}
static int kb_hit(void)
{
int c = 0;
newt.c_cc[VMIN] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
c = getc(stdin);
newt.c_cc[VMIN] = 1;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
if (c != -1) {
ungetc(c, stdin);
return 1;
}
return 0;
}
int main(void)
{
int c;
kb_init();
printf("Press ESC several times\n");
while (1) {
c = getchar();
if ((c == 27) && (kb_hit() == 0)) {
printf("You pressed ESC\n");
} else
if (c == '\n') {
break;
}
}
return 0;
}
但它只在第一次有效,第二次按退出键时,终端不接受更多数据。它不会完全冻结,因为提示会一直闪烁,但按更多键不会改变任何内容。
【问题讨论】:
-
在 Linux 上为我工作。你试过在调试器下运行它吗?
-
谢谢@n.m.,是的,它在 Debian 上也适用于我,Mavericks 没有 gdb 也没有 valgrind,不是我的笔记本电脑,我无法安装它:(
-
我听说在 OSX 上将 VMIN 恢复为 1 并不总是有效。 bitbucket.org/techtonik/python-pager/issues/5/…。不知道如何应对。
标签: c macos terminal xterm termios