Экранирующий символ «Backspace» '\ b': неожиданное поведение? - PullRequest
88 голосов
/ 22 июля 2011

Итак, я, наконец, читаю K & R , и я узнал кое-что на первых нескольких страницах, что есть экранирующий символ возврата на обратную сторону, \b.

Итак, я иду проверить это, и есть очень странное поведение:

#include <stdio.h>

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

Выход

hello wodl

Может кто-нибудь объяснить это?

Ответы [ 5 ]

128 голосов
/ 22 июля 2011

Ваш результат будет зависеть от типа терминала или консольной программы, но да, на большинстве \b это неразрушающий возврат.Он перемещает курсор назад, но не стирает то, что там есть.

Так что для части hello worl код выводит

hello worl
          ^

... (где ^ показывает гдекурсор) Затем он выводит два символа \b, которые перемещают курсор назад на два места без стирания (на вашем терминале):

hello worl
        ^

Обратите внимание, что курсор теперь находится на r.Затем он выводит d, который перезаписывает r и дает нам:

hello wodl
         ^

Наконец, он выводит \n, который является неразрушающим символом новой строки (опять же, на большинстве терминалов, включая, по-видимому,ваш), поэтому l остается без изменений, а курсор перемещается в начало следующей строки.

119 голосов
/ 22 июля 2011
..........
^ <= pointer to "print head"
            /* part1 */
            printf("hello worl");
hello worl
          ^ <= pointer to "print head"
            /* part2 */
            printf("\b");
hello worl
         ^ <= pointer to "print head"
            /* part3 */
            printf("\b");
hello worl
        ^ <= pointer to "print head"
            /* part4 */
            printf("d\n");
hello wodl

^ <= pointer to "print head" on the next line
42 голосов
/ 22 июля 2011

Если вам нужен разрушительный возврат, вам понадобится что-то вроде

"\b \b"

т.е. Backspace, пробел и еще один Backspace.

8 голосов
/ 22 июля 2011

Объяснить несложно ... Это все равно, что набрать hello worl, дважды нажать клавишу со стрелкой влево, набрать d и нажать клавишу со стрелкой вниз.

По крайней мере, этоВот как я понимаю, что ваш терминал интерпретирует коды \b и \n.

Перенаправьте вывод в файл, и я уверен, что вы получите что-то еще полностью.Хотя вам, возможно, придется взглянуть на байты файла, чтобы увидеть разницу.

[править]

Для уточнения, printf выдает последовательность байтов: hello worl^H^Hd^J, где^H является символом ASCII # 8, а ^J является символом ASCII # 10.То, что вы видите на экране, зависит от того, как ваш терминал интерпретирует эти контрольные коды.

1 голос
/ 27 ноября 2011

Используйте одну клавишу возврата после каждого символа printf("hello wor\bl\bd\n");

...