«Escape-space» escape-символ «\ b»: неожиданное поведение?

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

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

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

Выход

 hello wodl 

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

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

Итак, для hello worl части, выходы кода

 Привет, мир!
           ^

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

 Привет, мир!
         ^

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

 hello wodl
          ^

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

  ..........
 ^ <= указатель на "печатающая головка" 
  /* part1 */ printf("hello worl"); 
  Привет, мир!
           ^ <= указатель на "печатающая головка" 
  /* part2 */ printf("\b"); 
  Привет, мир!
          ^ <= указатель на "печатающая головка" 
  /* part3 */ printf("\b"); 
  Привет, мир!
         ^ <= указатель на "печатающая головка" 
  /* part4 */ printf("d\n"); 
  hello wodl

 ^ <= указатель на «печатающая головка» на следующей строке 

Если вы хотите разрушительное backspace, вам нужно что-то вроде

 "\b \b" 

т.е. обратное пространство, пробел и другое обратное пространство.

Не слишком сложно объяснить … Это похоже на написание hello worl , дважды нажатие клавиши со стрелкой влево, ввод d и нажатие клавиши со стрелкой вниз.

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

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

[редактировать]

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

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

  • Опубликованные данные UTF-8 на сервер теряют определенные символы
  • Является ли двоеточие `:` безопасным для использования дружественного URL-адреса?
  • Преобразование символов, акцентированных букв на английский алфавит
  • Какие символы нужно избегать при использовании Bash?
  • как блокировать или ограничивать специальные символы из полей ввода с помощью jquery?
  • Давайте будем гением компьютера.