对有趣的printf()语句感到困惑

时间:2014-11-30 15:07:06

标签: c printf

通过阅读this code,我偶然发现了以下printf()声明:

// reset, hide cursor and clear screen
printf("\e[0m\e[?25l\e[2J");

我必须承认我不是一名完全合格的C黑客,并且不完全理解这一点。我调整了周围,删除了论点,我理解它的作用(好吧,评论实际上说了一切),但我不知道它是如何完成的。此外,这有点难以谷歌。

printf()调用如何工作?

2 个答案:

答案 0 :(得分:12)

这与printf没有任何关系。 C11标准列出了§5.2.2中的转义序列,该列表包含\a\b\f\n\r,{{1 }和\t。作为扩展,GCC认为\v是一个转义序列,代表ASCII字符 Esc \e也可以,或者您的编译器可能支持它们都不是。请参阅编译器的文档)。以下是不可移植的control sequences。它们不能保证在所有终端中都能正常工作,甚至根本不能工作。最好的方法是查阅系统文档。

§6.4.4.4也描述了八进制转义序列。例如,\E,其中\033是十进制的033,因此是ASCII中的转义字符。同样,您可以使用27,这是一个指定相同字符的十六进制转义序列。

如果我们使用\x1b检查该计划的输出,则会显示od -c

033

ANSI转义序列由终端仿真器解释。 C将八进制/十六进制转义序列转换为ASCII Esc 字符。您的编译器作为扩展,也可以转换(✿´‿`) ~/test> ./a.out | od -c 0000000 033 [ 0 m 033 [ ? 2 5 l 033 [ 2 J 0000016 \e。根据要求,简要说明控制序列正在做什么:

  • \E:重置所有SGR属性
  • [0m:隐藏光标
  • [?25l:来自维基百科:

      

    清除部分屏幕。如果[2J为0(或缺失),则从光标清除   到屏幕结束。如果n为1,则从光标到开头清除   屏幕。如果n为2,请清除整个屏幕...

答案 1 :(得分:7)

printf()调用只是输出一系列特定的字节值。 "魔术"这些值在终端中是特殊的。

以ASCII" escape"开头的一系列特殊字节字符被称为"转义序列"。这些是为串行数据终端发明的,其中与终端通信的唯一方法是通过串行连接发送字节值。普通字符只是简单地显示在终端上,但最好有办法移动光标,清除屏幕等,大多数终端都使用了转义序列。

http://en.wikipedia.org/wiki/Escape_sequence

有一个名为" VT100"的特别受欢迎的终端,今天大多数终端仿真器都使用VT100转义序列。

即使在今天,转义序列也很有用。您可以编写一个简单的C程序,它可以在Linux,Mac,Windows,移动设备上的终端仿真器上运行,基本上无处不在。当你需要做一些简单的事情,比如清除屏幕时,输出正确的转义序列是最简单的方法。