所以我尝试将每个按键打印为引用 ASCII 代码的整数和字符。看来我无法打印一些控制字符。
在阅读了 antirez 关于他的 kilo 文本编辑器的小册子后,我设法禁用了 ctrl + c、z、s、q。所有这些将分别打印 3 26 19 17。 但我似乎无法禁用 ctrl + v ,根据他的指南,我应该关闭 IEXTEN ,如下面的代码所示。当我的 ctrl + v 应该返回 22 时,它似乎返回了剪贴板中的任何内容。
void enableRawMode(){
tcgetattr(STDIN_FILENO, &orig_termios);
atexit(disableRawMode);
struct termios raw = orig_termios;
tcgetattr(STDIN_FILENO, &raw);
raw.c_iflag &= ~( ICRNL | IXON );
raw.c_lflag &= ~( ECHO | ICANON | IEXTEN | ISIG );
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}
int main(){
enableRawMode();
char c;
while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q'){
if (iscntrl(c)){
printf("%d\n", c);
}
else{
printf("%d ('%c')\n", c, c);
}
}
return 0;
}
有人知道为什么会发生这种情况吗?有什么替代解决方案吗?我在 WSL 终端上运行了这个,这有什么关系吗?
终端和您的程序(在主机上运行)之间的通信是双向的。字节从终端发送到主机(响应您的 read() 调用),字符串从主机发送到终端(通过 printf())。
正如 @Barmar 所说,您的终端不会将 ^V 字符发送到主机,并且您的程序永远不会收到它。
仅供澄清:终端驱动程序是在主机上运行的操作系统代码(在本例中是在 Linux VM 内),通过禁用某些控制字符,您只是告诉驱动程序(而不是终端本身)它不能在将这些字符发送到您的进程(即您的代码)之前(或代替)对它们进行任何特殊处理。
顺便说一句,您的示例中缺少某些内容(
orig_termios
变量?)。