在 ncurses 中捕获 control+key 的正确方法是什么?当前我在做它定义这样的控制:
#define ctl(x) ((x) & 0x1f)
Run Code Online (Sandbox Code Playgroud)
它工作正常,但问题是我无法同时捕捉 Cj 和 ENTER,这是因为:
j = 106 = 1101010
0x1f = 31 = 0011111
1101010 & 0011111 = 0001010 = 10 = ENTER key..
Run Code Online (Sandbox Code Playgroud)
那么..我该如何抓住它?谢谢!
-- 编辑:如果我尝试下面的代码,我无法正确捕捉回车键,即使在数字键盘中也是如此。Enter 被捕获为 ctrl-j。
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int main(void) {
initscr();
int c = getch();
nonl();
switch (c) {
case KEY_ENTER:
printw("key: %c", c);
break;
case ctrl('j'):
printw("key: ctrl j");
break;
}
getch();
endwin();
return;
}
Run Code Online (Sandbox Code Playgroud)
新代码:
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int main(void) {
initscr();
int l = -1;
int c = getch();
cbreak();
noecho();
nonl();
keypad(stdscr, TRUE);
switch (c) {
case KEY_ENTER:
printw("key: %c", c);
break;
case ctrl('j'):
printw("key: ctrl j");
break;
}
printw("\nnow press a key to end");
getch();
endwin();
return;
}
Run Code Online (Sandbox Code Playgroud)
尝试nonl:
和例程控制底层显示设备是否在输入时将
nl返回nonl键转换为换行符,以及是否在输出时将换行符转换为返回和换行(在任何一种情况下,都call addch('\n')相当于虚拟屏幕上的返回和换行) 。最初,这些翻译确实发生了。如果使用 nonl 禁用它们,curses 将能够更好地利用换行功能,从而加快光标移动速度。此外,curses 将能够检测到返回键。
进一步阅读:手册页的注释部分getch:
通常,KEY_ENTER 表示数字键盘上的 Enter 键发送的字符:
- 终端描述列出了最有用的键,
- 常规键盘上的 Enter 键已经由标准 ASCII 字符处理,用于回车和换行,
根据是否调用了 nl 或 nonl,在常规键盘上按“Enter”可能会返回回车符或换行符,最后
“输入或发送”是该键的标准描述。
这解决了有关换行符/回车符翻译的问题。后续评论提醒您指出,手册页在初始化部分提供了基本建议:
为了获得一次一个字符的输入而不产生回显(大多数交互式、面向屏幕的程序都需要这样),应该使用以下序列:
initscr(); cbreak(); noecho();
Run Code Online (Sandbox Code Playgroud)
并且OP的示例程序没有使用cbreak(或raw)。手册页cbreak说
通常,tty 驱动程序会缓冲键入的字符,直到键入换行符或回车符为止。该
cbreak例程禁用行缓冲和擦除/终止字符处理(中断和流控制字符不受影响),使用户键入的字符立即可供程序使用。该nocbreak例程将终端返回到正常(煮熟)模式。最初,终端可能处于也可能不处于 cbreak 模式,因为该模式是继承的;因此,程序应该显式调用
cbreakornocbreak。 大多数使用curses 的交互程序都会设置cbreak 模式。请注意,cbreak覆盖raw. (有关这些例程如何与和交互的讨论,请参阅curs_getch(3x)。)echonoecho
另外,curs_getch您可能会读到
如果
keypad为 TRUE,并且按下功能键,则返回该功能键的标记而不是原始字符:
- 预定义的功能键以宏的形式列出
<curses.h>,其值超出 8 位字符的范围。他们的名字以 开头KEY_。
也就是说,只有KEY_ENTER在程序调用以下命令时, curses 才会返回keypad:
keypad(stdscr, TRUE);
Run Code Online (Sandbox Code Playgroud)
为了方便讨论,下面是一个修复示例程序截至 5 月 17 日的一些问题的示例:
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int
main(void)
{
int c;
initscr();
keypad(stdscr, TRUE);
cbreak();
noecho();
nonl();
c = getch();
switch (c) {
case KEY_ENTER:
printw("\nkey_enter: %d", c);
break;
case ctrl('j'):
printw("\nkey: ctrl j");
break;
default:
printw("\nkeyname: %d = %s\n", c, keyname(c));
break;
}
printw("\nnow press a key to end");
getch();
endwin();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
也就是说,你必须调用keypadbefore getch,并且返回的值KEY_ENTER不是字符(不能用 打印%c)。
使用通常的终端描述在 Linux 控制台上运行,您将只看到数字键盘的回车符Enter,因为该描述不使用应用程序模式。Linux控制台确实支持应用程序模式,可以写相应的描述。作为快速检查(存在差异......),您可以设置TERM=vt100查看KEY_ENTER.
| 归档时间: |
|
| 查看次数: |
4109 次 |
| 最近记录: |