什么和\ b做什么?

我期待这段简单的代码

printf("foo\b\tbar\n"); 

用“\ t”替换“o”并产生以下输出

 fo bar 

(假设每8个字符发生制表位)。 相反,我得到了

 foo bar 

似乎我的shell将\ b解释为“将游标向后移动一个位置”和\ t为“将光标移动到下一个制表位”。 这种行为是否特定于我正在运行代码的shell? 我应该期望不同系统有不同的行为吗?

退格键和制表符都移动光标位置。 两者都不是真正的“可打印”角色。

你的代码说:

  1. 打印“foo”
  2. 将光标移回一个空格
  3. 将光标向前移动到下一个tabstop
  4. 输出“bar”。

要获得您期望的输出,您需要printf("foo\b \tbar") 。 注意额外的“空间”。 说的是:

  1. 输出“foo”
  2. 将光标移回一个空格
  3. 输出”(这取代了第二个’o’)。
  4. 将光标向前移动到下一个tabstop
  5. 输出“bar”。

大多数情况下,使用制表符和退格键来格式化程序输出是不合适的。 学习使用printf()格式说明符。 选项卡的渲染可能会根据输出的查看方式而有很大差异。

这个小脚本显示了一种改变终端标签渲染的方法。 在Ubuntu + gnome-terminal上测试:

 #!/bin/bash tabs -8 echo -e "\tnormal tabstop" for x in `seq 2 10`; do tabs $x echo -e "\ttabstop=$x" done tabs -8 echo -e "\tnormal tabstop" 

另见man settermregtabs

如果您重定向输出或只是写入文件,标签通常会显示为少于标准的8个字符,特别是在“编程”编辑器和IDE中。

所以用其他词来说:

 printf("%-8s%s", "foo", "bar"); /* this will ALWAYS output "foo bar" */ printf("foo\tbar"); /* who knows how this will be rendered */ 

恕我直言,标签一般很少适合任何事情。 exception可能是为需要制表符分隔值输入文件的程序生成输出(类似于逗号分隔值)。

退格'\b'是一个不同的故事…它永远不应该用于创建文本文件,因为它只会使文本编辑器吐出垃圾。 但它在编写交互式命令行程序时确实有许多应用程序,而单独使用格式字符串是无法实现的。 如果您发现自己需要它,请查看“ncurses”,这样可以更好地控制输出在终端屏幕上的位置。 通常,由于它是2011年而不是1995年,因此对于高度交互的程序来说,GUI通常更容易处理。 但同样,也有例外。 就像为新的脚本语言编写telnet服务器或控制台一样。

不,这或多或少都是他们的意图。

在C(以及许多其他语言)中,您可以使用\ notation插入难以查看/输入字符:

  • \a是警报/铃声
  • \b是退格/退出
  • \n是换行符
  • \r是回车(返回左边距)
  • \t是标签

您还可以使用\0 nnn指定任何字符的八进制值,或使用\x nn指定任何字符的hex值。

  • EG: _的ASCII值是八进制137,hex5f,所以它也可以键入\0137\x5f ,如果你的键盘没有_键或其他东西。 这对于NUL( \0 )和ESC( \033 )等控制字符更有用

有人发布(然后在我给它+1之前删除了他们的答案),还有一些不常用的:

  • \f是换页/新页面(从打印机弹出页面)
  • \v是垂直制表符(向下移动一行,在同一列上)

在屏幕上, \f通常与\v相同,但在某些打印机/电传打字机上,它会一直显示到下一张纸/纸上。

C标准(实际上是C99,我不是最新的)说:

表示执行字符集中的非图形字符的字母转义序列旨在在显示设备上产生如下操作:

\b (退格键)将活动位置移动到当前行的上一个位置。 […]

\t (水平制表符)将活动位置移动到当前行的下一个水平制表位置。 […]

两者都只是移动活动位置,都不应该在另一个字符上或上面写任何字符。 要使用空格覆盖,您可以尝试: puts("foo\b \tbar"); 但请注意,在某些显示设备上 – 例如菊花轮打印机 – o将显示透明空间。

此行为是特定于终端的,由您使用的终端仿真器(例如xterm )和它提供的终端的语义指定。 终端行为在过去20年中一直非常稳定,您可以合理地依赖\b的语义。

\t是制表符,并且正在根据\b的操作执行您正在预期的操作 – 它转到下一个制表位,然后递减,然后转到下一个制表位(在这种情况下)相同的制表位,因为\b