我正在尝试了解终端 I/O 的工作原理。
当终端处于非规范模式时(缺少错误处理):
struct termios term_original, term_current;
tcgetattr(STDIN_FILENO, &term_original);
term_current = term_original;
term_current.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
term_current.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | ISTRIP | IXON | PARMRK);
term_current.c_oflag &= ~(OPOST);
term_current.c_cc[VMIN] = 1;
term_current.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSADRAIN, &term_current);
一个简单的读取循环可以读入每次按下按钮所产生的数据,如下所示:
char c;
while (read(0, &c, 1) != -1) { PRINT_CHAR(c); }
现在,
- 按键盘上的 Esc 键生成:0x1b。
- 按 F1 生成:0x1b 0x4f 0x50。
- 按 F5 生成:0x1b 0x5b 0x31 0x35 0x7e。
在读取和处理此输入方面,如何确定按下一个按钮的输出在何处结束以及下一个按钮的输出从何处开始?我找不到可辨别的模式,事实上 Esc 生成一个字节,它也与大多数多字节生成按钮按下的输出的第一个字节相同,这似乎表明没有。是否有其他机制可以确定按钮边界的位置?
最佳答案
程序依赖于不能按得太快的按键。如果延迟小于 100ms,这是一键按下;否则会有两个单独的事件。
是的,程序实际上在按下 ESC 后暂停了一段时间,以确保它是 ESC 而不是其他键。有时可以用肉眼辨别这种停顿。
一些程序识别 ESCDELAY 环境变量来微调这个时间。
是的,这并不完美,您可以通过按键太快来欺骗系统。
关于c - 在非规范模式下使用终端 IO 确定按钮边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16513045/