Что делают \t и\b?
Я ожидаю, что эта простая строка кода
printf("foo\b\tbar\n");
заменить "o" на "\ t" и произвести следующий вывод
fo bar
(при условии, что табуляция происходит каждые 8 символов).
Наоборот, я получаю
foo bar
Кажется, что моя оболочка интерпретирует \b как "переместить курсоры на одну позицию назад" и \t как "переместить курсор на следующую вкладку". Является ли это поведение специфичным для оболочки, в которой я запускаю код? Должен ли я ожидать различного поведения в разных системах?
Ответы
Ответ 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
.