【问题标题】:C++ Ansi escape codes and it's interpretation when done manuallyC++ Ansi 转义码及其在手动完成时的解释
【发布时间】:2016-05-26 16:41:35
【问题描述】:

我只是偶然注意到这一点,代码如下。在下面的代码中,

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

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

【问题讨论】:

  • 我投票结束这个问题,因为它更适合 unix.stackexchange.com。

标签: c++ bash ansi ansi-escape


【解决方案1】:

Unix 终端是一个非常复杂的野兽。 Posix 包含一个pretty thorough description 的特性;以下只是一个简短的总结。

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

当驱动程序读取输入字符时,它会检查某些特殊字符;其他任何内容都会添加到行缓冲区并回显到终端设备。 (终端设备的输入和输出是独立的;如果驱动程序或程序没有回显输入,则屏幕上不会出现任何内容,这通常会令人困惑。程序关闭回显是为了能够接受密码,例如例子。)

所有特殊字符都是可配置的。有很多;以下是一些较常见的:

  • Enter 将换行符插入缓冲区,并终止输入行,以便等待读取将返回。
  • 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[ 开头。例如,向上箭头发送代码 ESC[A,因此如果您正在运行一个不处理光标移动的幼稚程序字符,当您按向上键时,您将看到 ^[[A 回显。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 2015-07-08
    • 2013-06-04
    相关资源
    最近更新 更多