什么和\ b做什么?

cim*_*ere 30 c printf

我期待这段简单的代码

printf("foo\b\tbar\n");
Run Code Online (Sandbox Code Playgroud)

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

fo     bar
Run Code Online (Sandbox Code Playgroud)

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

foo    bar
Run Code Online (Sandbox Code Playgroud)

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

BRP*_*ock 34

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

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

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

您也可以指定使用任何字符的八进制值\0NNN,或任何字符与十六进制值\xNN.

  • EG:ASCII值_是八进制137,十六进制5f,因此它也可以键入,\0137或者\x5f,如果您的键盘没有_键或其他东西.这对于像NUL(\0)和ESC(\033)这样的控制字符更有用

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

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

在屏幕上,\f通常工作方式相同\v,但在某些打印机/电视类型上,它将一直到下一张纸/纸.

  • 我应该注意到,有一个传统(许多终端都支持),就像在打字机上一样,通过交替退格和 _(下划线)字符来给文本加下划线,并通过键入 <字符> \b <相同字符> 来加粗。这已经不太流行了,但是你可以在像 roff 这样的地方遇到它。在 Linux/Unix 中,程序 `ul` 会将这些转换为 ANSI 转义码,但可能会起作用: `printf " • u\b_n\b_d\b_e\b_r\b_l\b_i\b_n\b_e\b_ B \bBO\bOL\bLD\bD \n" | 乌尔` (2认同)

Bri*_*and 30

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

你的代码说:

  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"
Run Code Online (Sandbox Code Playgroud)

另见 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 */
Run Code Online (Sandbox Code Playgroud)

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

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