“退格”转义字符'\ b':意外行为?


101

因此,我最终阅读了K&R,并且在前几页中学到了一些知识,即有一个退格转义字符\b

所以我去测试一下,有一些非常奇怪的行为:

#include <stdio.h>

main ()
{
    printf("hello worl\b\bd\n");
}

输出是

hello wodl

谁能解释一下?

Answers:


145

根据您所使用的终端或控制台程序的类型,您的结果将有所不同,但是可以,大多数情况下\b无损退格键。它将光标向后移动,但不会擦除其中的内容。

所以对于这hello worl部分,代码输出

你好世界
          ^

...(其中^显示光标所在的位置),然后输出两个\b字符,该字符将光标向后移动两个位置而不会擦除(在您的终端上):

你好世界
        ^

请注意,光标现在位于上r。然后输出d,将覆盖r并给出:

你好沃德尔
         ^

最后,它输出\n,这是一个非破坏性的换行符(同样,在大多数终端上,包括您的终端上),因此l保持不变,并将光标移至下一行的开头。


1
如果不擦除,为什么“ r”消失了?
cesoid

1
@cesoid:“您的结果会根据您所使用的终端或控制台程序的类型而有所不同”
TJ Crowder

只是您的示例不适合输出,因此它不是可能解释的示例。
cesoid

5
@cesoid r被替换为d。解释仍然合适。
syockit'6

1
@cesoid:对终端感兴趣。在Windows中,cmd.execommand.com终端并非总是插入(您可以使用Ins键切换行为)。我很惊讶地发现我的* nix主计算机上的Gnome Terminal总是插入,甚至似乎都不喜欢它,而不是基于Ins键的切换。以前从未注意到。显然,我几乎从来不想打字。:-)
TJ Crowder

122
.....
^ <=指向“打印头”的指针
            /* part1 */
            printf("hello worl");
你好世界
          ^ <=指向“打印头”的指针
            /* part2 */
            printf("\b");
你好世界
         ^ <=指向“打印头”的指针
            /* part3 */
            printf("\b");
你好世界
        ^ <=指向“打印头”的指针
            /* part4 */
            printf("d\n");
你好沃德尔

^ <=指向下一行“打印头”的指针

如果第4部分之后的光标位于'l'字母上,是否不应该将其替换为'\ n'?(导致“您好”)
lucas_turci

@lucas_turci:问题是'\n'屏幕上没有显示。已经存在的东西保持不变;不能用空格或任何其他字符表示代替。
pmg 2013年

44

如果您想要破坏性的退格键,则需要类似

"\b \b"

即退格,空格和另一个退格。


这仍然留下空格字符吗?
Pacerier

好吧,是的,但是后续操作\b将意味着下一个输出字符将覆盖它。
彼得·K

1
如果有什么没有后续的性格吗?
Pacerier 2014年

那没关系,不是吗?
彼得·K。

1
嗯 除非您的设备实现了“删除最后一个字符”选项(例如DEL / 0x7f),否则我很困惑。
彼得·K。

8

不太难解释...这就像键入hello worl,敲击两次左箭头键,键入d并敲击向下箭头键。

至少,这就是我推断您的终端插入\b\n代码的方式。

将输出重定向到文件,我敢打赌您会完全得到其他东西。尽管您可能必须查看文件的字节才能看到区别。

[编辑]

为了详细说明,它printf发出一个字节序列:hello worl^H^Hd^J,其中^HASCII字符#8和^JASCII字符#10。屏幕上显示的内容取决于终端如何解释这些控制代码。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.