Подтвердить что ты не робот

Что делают \t и\b?

Я ожидаю, что эта простая строка кода

printf("foo\b\tbar\n");

заменить "o" на "\ t" и произвести следующий вывод

fo     bar

(при условии, что табуляция происходит каждые 8 ​​символов). Наоборот, я получаю

foo    bar

Кажется, что моя оболочка интерпретирует \b как "переместить курсоры на одну позицию назад" и \t как "переместить курсор на следующую вкладку". Является ли это поведение специфичным для оболочки, в которой я запускаю код? Должен ли я ожидать различного поведения в разных системах?

4b9b3361

Ответ 1

Backspace и вкладка перемещают позицию курсора. Также не является "печатным" характером.

В вашем коде говорится:

  • напечатать "foo"
  • переместите курсор назад на одно пробел.
  • переместите курсор вперед к следующей вкладке
  • вывод "bar".

Чтобы получить ожидаемый результат, вам нужно printf("foo\b \tbar"). Обратите внимание на дополнительное "пространство". Это говорит:

  • вывод "foo"
  • переместите курсор назад на одно пробел.
  • output a '' (это заменяет второй "o" ).
  • переместите курсор вперед к следующей вкладке
  • вывод "bar".

В большинстве случаев неуместно использовать вкладки и backspace для форматирования вывода вашей программы. Научитесь использовать спецификаторы форматирования printf(). Оказание вкладок может сильно варьироваться в зависимости от того, как просматривается вывод.

Этот маленький script показывает один из способов изменить отображение вкладки в терминале. Протестировано на 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"

Также см. man setterm и regtabs.

И если вы перенаправляете свой вывод или просто записываете в файл, вкладки обычно будут отображаться как меньше, чем стандартные 8 символов, особенно в "программировании" редакторов и IDE.

Итак, другими словами:

printf("%-8s%s", "foo", "bar"); /* this will ALWAYS output "foo     bar" */
printf("foo\tbar"); /* who knows how this will be rendered */

IMHO, вкладки вообще редко подходят для чего-либо. Исключением может быть генерация вывода для программы, для которой требуются входные файлы с разделителями-разделителями (аналогично значению, разделенному запятыми).

Backspace '\b' - это совсем другая история... его никогда не следует использовать для создания текстового файла, поскольку он просто заставит текстовый редактор выплевывать мусор. Но в нем есть много приложений для написания интерактивных программ командной строки, которые невозможно выполнить только с помощью строк формата. Если вам это очень нужно, проверьте "ncurses", что дает вам гораздо лучший контроль над тем, где ваш вывод идет на экране терминала. И, как правило, с 2011 года, а не с 1995 года, GUI, как правило, легче иметь дело с высоко интерактивными программами. Но опять же, есть исключения. Как написать сервер telnet или консоль для нового языка сценариев.

Ответ 2

Нет, это более или менее то, что они должны делать.

В C (и многих других языках) вы можете вставлять символы с жестким доступом/типом, используя обозначение \:

  • \a является предупреждением/звонком
  • \b - это backspace/rubout
  • \n - это символ новой строки
  • \r - возврат каретки (возврат к левому краю)
  • \t есть вкладка

Вы также можете указать восьмеричное значение любого символа, используя \0 nnn, или шестнадцатеричное значение любого символа с \x nn.

  • EG: значение ASCII _ - восьмеричное значение 137, hex 5f, поэтому его также можно ввести \0137 или \x5f, если на клавиатуре не было ключа _ или что-то в этом роде. Это более полезно для управляющих символов, таких как NUL (\0) и ESC (\033)

Как кто-то опубликовал (затем удалил свой ответ, прежде чем я смог его добавить +1), есть и некоторые менее часто используемые:

  • \f является формой feed/new page (страница извлечения из принтера).
  • \v - вертикальная вкладка (перемещение вниз по одной строке в том же столбце)

На экранах \f обычно работает так же, как \v, но на некоторых принтерах/телетайпах он будет перейдите к следующей форме/листу бумаги.

Ответ 3

Стандарт C (фактически C99, я не обновляюсь) говорит:

Алфавитные escape-последовательности, представляющие неграфические символы в наборе символов выполнения, предназначены для создания действий на устройствах отображения следующим образом:

\b (backspace) Перемещение активной позиции в предыдущую позицию на текущей строке. [...]

\t (горизонтальная вкладка) Перемещение активной позиции в следующую горизонтальную позицию табуляции в текущей строке. [...]

Оба просто перемещают активную позицию, ни одна из них не должна писать символ на другом символе или над ним. Чтобы перезаписать пробел, вы можете попробовать: puts("foo\b \tbar");, но обратите внимание, что на некоторых устройствах отображения - скажем, на розовом принтере - o отобразит прозрачное пространство.

Ответ 4

Это поведение зависит от терминалов и определяется используемым терминальным эмулятором (например, xterm) и семантикой терминала, который он предоставляет. Поведение терминала очень стабильно в течение последних 20 лет, и вы можете обоснованно полагаться на семантику \b.

Ответ 5

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