Характер втечі "backspace" "\ b": несподівана поведінка?


101

Отже, я нарешті читаю K&R , і я дізнався щось на перших сторінках про те, що є символ втечі із зворотної області \b.

Тож я йду перевірити це, і є дуже дивна поведінка:

#include <stdio.h>

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

Вихід є

hello wodl

Хтось може це пояснити?

Відповіді:


145

Результат варіюватиметься залежно від того, на якому терміналі чи консольній програмі ви працюєте, але так, для більшості \b- це неруйнівна резервна область. Він переміщує курсор назад, але не стирає те, що там є.

Отже, для hello worlчастини, код виводить

привіт Worl
          ^

... (де ^показано, де знаходиться курсор) Потім він видає два \bсимволи, які переміщують курсор назад на два місця, не стираючи (на своєму терміналі):

привіт Worl
        ^

Зверніть увагу, що курсор зараз на r. Потім він виводить d, що перезаписує rта дає нам:

привіт водл
         ^

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


1
Якщо це не стирається, то чому "r" пішов?
цезоїд

1
@cesoid: "Ваш результат буде залежати від того, на якому терміналі чи консольній програмі ви працюєте"
TJ Crowder

Просто ваш приклад не відповідає результату, тому це не приклад можливого пояснення.
цезоїд

5
@cesoid The rзамінено на d. Пояснення все-таки підходить.
syockit

1
@cesoid: цікаво про термінал. У Windows, термінали cmd.exeта command.comтермінали не завжди вставляються (ви можете використовувати клавішу Ins, щоб переключити поведінку). Я здивовано виявив, що Gnome Terminal на моєму головному * nix-комп’ютері завжди вставляється, навіть не здається, що він надає перевагу йому набагато менше перемикань на основі клавіші Ins. Ніколи цього не помічав. Ясно, що я майже ніколи не хочу вводити текст. :-)
TJ Crowder

122
..........
^ <= покажчик на "друкуючу голівку"
            /* part1 */
            printf("hello worl");
привіт Worl
          ^ <= покажчик на "друкуючу голівку"
            /* part2 */
            printf("\b");
привіт Worl
         ^ <= покажчик на "друкуючу голівку"
            /* part3 */
            printf("\b");
привіт Worl
        ^ <= покажчик на "друкуючу голівку"
            /* part4 */
            printf("d\n");
привіт водл

^ <= вказівник на "друкуючу головку" у наступному рядку

Якщо курсор після частини 4 знаходиться на букві 'l', чи не слід його замінювати на '\ n'? (в результаті "привіт Wor")
lucas_turci

@lucas_turci: річ у тому, що '\n'на екрані немає представництва. Те, що вже є, залишається тим самим; не замінюється пробілом або будь-яким іншим поданням символів.
pmg

44

Якщо ви хочете руйнувати задній простір, вам знадобиться щось на кшталт

"\b \b"

тобто простору, простору та іншої.


Це все ще залишає космічний персонаж, чи не так?
Pacerier

Ну, так, але подальший \bозначатиме, що наступний вихідний символ замінить його.
Петро К.

1
Що робити, якщо немає наступного символу?
Pacerier

Тоді це не має значення, чи не так?
Петро К.

1
Хм. Якщо ваш пристрій не реалізує параметр "видалити останній символ" (наприклад, DEL / 0x7f), я наткнувся.
Петро К.

8

Не надто важко пояснити ... Це як набрати текст hello worl, двічі натиснути клавішу зі стрілкою ліворуч, набрати dта натиснути клавішу зі стрілкою вниз.

Принаймні, саме так я вважаю, що ваш термінал перетинає \bі \nкоди.

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

[редагувати]

Щоб трохи уточнити, це printfвипромінює послідовність байтів: hello worl^H^Hd^Jде ^Hсимвол ASCII № 8 і ^Jсимвол ASCII №10. Те, що ви бачите на екрані, залежить від того, як ваш термінал інтерпретує ці коди управління.


1

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


"привіт wod \ n"? Що це означає?
Еліас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.