【发布时间】:2021-03-26 23:28:45
【问题描述】:
我正在用 C++ 编写 readline 替换,我想以原始模式处理终端输入,包括特殊/转义键,如“向上箭头”\e[A。但是,我还希望能够区分单按退出键 \e 然后按 [ 和按 A 与按向上箭头。
我认为这两种情况之间的主要区别在于,当按下向上箭头时,输入字符会在不到一毫秒的时间内输入,所以我想我可以这样做:
#include <termios.h>
#include <absl/strings/escaping.h>
#include <iostream>
termios enter_raw() {
termios orig;
termios raw;
tcgetattr(STDOUT_FILENO, &orig);
tcgetattr(STDOUT_FILENO, &raw);
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag &= ~OPOST;
raw.c_cflag |= CS8;
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
raw.c_cc[VMIN] = 1;
raw.c_cc[VTIME] = 0;
tcsetattr(STDOUT_FILENO, TCSAFLUSH, &raw);
return orig;
}
int main() {
termios orig = enter_raw();
while(true) {
char buf[10];
memset(buf, 0, sizeof(buf));
std::cin >> buf[0];
usleep(1000);
int actual = std::cin.readsome(buf + 1, sizeof(buf) - 2);
std::cout << "Got string: \"" << absl::CEscape(buf) << "\"\n";
if(buf[0] == 35) { break; } // received ctrl-c
}
tcsetattr(STDOUT_FILENO, TCSAFLUSH, &orig);
return 0;
}
然而,这个输出不是我希望的Got string: "\033[A";相反,它会执行三次Got string,就像它只是一个简单的字符循环一样。改变它休眠的微秒数似乎不会影响任何事情。
有没有办法在 C++ 中轻松实现这种东西?它可以移植到大多数终端吗?我不在乎支持Windows。答案不用<iostream>;只要能完成工作,它就可以使用 C 风格的终端 IO。
【问题讨论】:
标签: c++ terminal ansi-escape vt100