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

Я ожидаю эту простую строку кода

printf("foobtbarn");

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

fo     bar

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

foo    bar

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

5 ответов


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

ваш код говорит:

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

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

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

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

этот маленький скрипт показывает один из способов изменить ваш отображение вкладки терминала. Протестировано на 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 символов, особенно в редакторах "программирование" и IDEs.

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

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, графический интерфейс как правило, легче иметь дело с для интерактивных программ. Но опять же, есть исключения. Как писать сервера telnet или консоли нового языка программирования.


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

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

  • \a сигнал/звонок
  • \b является backspace / rubout
  • \n это newline
  • \r возврат каретки (возврат к левому краю)
  • \t is tab

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

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

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

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

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


стандарт C (на самом деле C99, я не в курсе) говорит:

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

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

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

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


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


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