C ++ Ansi转义代码及其手动完成时的解释

时间:2016-05-26 16:41:35

标签: c++ bash ansi ansi-escape

我只是意外地注意到这一点,使用以下代码。在以下代码中,

char teststring[20];
cin.getline(teststring, 20);

提示停止用户输入,当我按下向上箭头时,我用肌肉记忆检查bash历史记录,它打印出Ansi Escape代码(从here获得详细信息){{ 1}}当我按下一个退格键并按下回车键时,字符^[[A被删除,它打印出一个不可读的垃圾,而不是A,但当我手动输入相同的键或复制时 - 再次禁止(为了确保它不是ASCII中的类似符号)没有最后一个字母,它打印^[[。 输入的字符是一样的原因是什么?

This is the output

1 个答案:

答案 0 :(得分:2)

Unix终端是一个非常复杂的野兽。 Posix包含pretty thorough description个功能;以下只是一个快速摘要。

通常,终端输入设备在"规范"模式。在该模式中,终端驱动程序维护行缓冲区,在必要时通过读取用户输入填充该行缓冲区。如果缓冲区已清空并且程序请求了更多数据,则驱动程序将在向程序提供更多数据之前读取整行输入。因此,如果缓冲区为空,即使getc读取单个字符,也会导致在getc返回之前将整个读入终端驱动程序的缓冲区。

当驱动程序读取输入字符时,它会检查某些特殊字符;其他任何东西都被添加到行缓冲区并回显给终端设备。 (对终端设备的输入和输出是独立的;如果驱动程序或程序没有回显输入,屏幕上什么都不会出现,这通常会让人感到困惑。程序会响起,以便能够接受密码,例如。)

所有特殊字符均可配置。有很多;这里有一些比较常见的:

  • 输入将新行字符插入缓冲区,并终止输入行,以便返回待处理的读取。
  • Ctrl-D EOF)字符本身被丢弃,但输入终止并且挂起的读取返回。如果输入缓冲区为空 - 即,在行的开头按下Ctrl-D,则会将零长度缓冲区返回到挂起的读取,这将被解释为文件结束标记。
  • Bksp ERASE)除非输入缓冲区为空,否则从输入缓冲区中删除最后一个字符并从屏幕上删除它。
  • Ctrl-C INTR)将SIGINT发送给流程。
  • Ctrl-Z SUSP)将SIGTSTP发送给流程。
  • Ctrl-U KILL)删除整个输入缓冲区。
  • Ctrl-S STOP)停止输出。
  • Ctrl-Q START)如果已使用STOP字符停止输出,则恢复输出。

当Linux终端驱动程序回显字符时,它通常会将控制字符(ascii代码小于0x20的字符)作为插入符号( ^ ),后跟代码高度为0x40的字符,这通常是一封信。 ESC字符的代码为0x1B,因此它通常会作为插入符号回显,后跟字符0x5B,这是一个空方括号。因此,您通常希望ESC^[回显。

键盘上的许多键实际上发送了多个字符,几乎所有这些序列都以 ESC [>开头。例如,uparrow发送代码 ESC [ A ,所以如果你正在运行一个无法处理的天真程序光标移动字符,当你按下向上箭头键时,你会看到^[[A回显。

您看到的字符是用于显示与任何Unicode字形不对应的字符的方式之一。该框包含四个十六进制数字,对应于Unicode代码点,在本例中为U + 001B,即ESC个字符。我不知道为什么会发生这种情况,但很可能是由于各种组件之间的竞争条件导致了终端回声。