在使用curses
orncurses
库的程序中,该getch()
函数可以识别普通字符(如'x'
)或箭头和功能键发送的转义序列。例如,键入向上箭头键可能会发送序列 (Escape, '[', 'A'),但getch()
会返回int
值KEY_UP
。它甚至使用时间信息来区分自己发送的转义字符和序列中的转义字符。
要getch()
成功使用,您首先必须调用initscr()
,它会清除屏幕,以便curses 可以控制显示的内容。
有没有一种方便的方法可以在不占用屏幕的情况下识别特殊键?理想情况下,我想在getch()
没有先调用的情况下调用initscr()
,并让它返回与调用时相同的值initscr()
,但实验表明这不起作用。
这是我正在尝试做的一个非工作示例。程序提示用户输入向上、向下、退出、向左、向右,并确认输入了正确的键。
-c
使用调用运行程序initscr()
并使其正常工作。不先调用-c
就运行它;所有调用都失败,无需等待输入,返回( )。getch()
initscr()
getch()
ERR
-1
// gcc arrows.c -o arrows -lncurses
#include <term.h>
#include <stdio.h>
#include <curses.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int use_curses = 0;
if (argc == 2 && strcmp(argv[1], "-c") == 0) {
use_curses = 1;
}
else if (argc != 1) {
fprintf(stderr, "Usage: %s [-c]\n", argv[0]);
exit(EXIT_FAILURE);
}
WINDOW *win;
if (use_curses) {
win = initscr();
cbreak();
noecho();
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
mvaddstr(0, 0, "Press UP, DOWN, Escape, LEFT, RIGHT");
}
else {
puts("Press UP, DOWN, Escape, LEFT, RIGHT");
}
int keys[5];
for (int i = 0; i < 5; i ++) {
keys[i] = getch();
}
int ok;
if (keys[0] == KEY_UP &&
keys[1] == KEY_DOWN &&
keys[2] == '\x1b' &&
keys[3] == KEY_LEFT &&
keys[4] == KEY_RIGHT)
{
ok = 1;
if (use_curses) {
mvaddstr(2, 0, "OK");
}
else {
puts("OK");
}
}
else {
ok = 0;
char message[100];
sprintf(message,
"Incorrect input: (%d, %d, %d, %d, %d)",
keys[0], keys[1], keys[2], keys[3], keys[4]);
if (use_curses) {
mvaddstr(2, 0, message);
}
else {
puts(message);
}
}
if (use_curses) {
mvaddstr(4, 0, "Press any key to quit ");
(void)getch();
endwin();
}
exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);
}
没有-c
选项的输出(在 Ubuntu 17.04 x86_64 上)是:
Press UP, DOWN, Escape, LEFT, RIGHT
Incorrect input: (-1, -1, -1, -1, -1)
更新:使用诅咒以外的解决方案会很好。它必须直接或间接地使用 terminfo 来了解要查找的输入序列。(在我看来,识别特殊键输入应该很简单,而不是与接管整个屏幕密切相关。)