Управляющий символ (control character) — это символ кодировки, которому не сопоставлено видимое изображение (глиф): вместо печати буквы он подает команду — перевести строку, сдвинуть на табуляцию, вернуть каретку в начало строки, подать звуковой сигнал. В таблице ASCII это коды 0x00-0x1F и 0x7F, всего 33 символа.
Содержание
Ниже разберу, чем управляющий символ отличается от видимого и от escape-последовательности, покажу таблицу управляющих кодов ASCII и на прогоняемых примерах Python пройду самые частые из них — \n, \r, \t — вместе с типовой ошибкой в путях Windows. Весь код в статье запущен, вывод в блоках — реальный.
Три разных понятия: не путать
В теме легко смешать три вещи, поэтому развожу их сразу на одном примере — символе перевода строки.
- Управляющий символ — это сам невидимый символ в памяти. Перевод строки — один символ с кодом 10 (0x0A), в тексте он не рисуется, а разрывает строку.
- Escape-последовательность — это способ записать такой символ в исходном коде обычными печатными знаками. В строке Python перевод строки пишут как
\n— два видимых знака в тексте программы, но в памяти это один символ. - Видимый (графический) символ — буква, цифра, знак препинания, у которого есть глиф:
A,7,?.
Цепочка получается такая: escape \n в исходнике -> один символ с кодом 0x0A в памяти -> эффект «новая строка» при выводе. Дальше проверю это кодом.
Управляющие символы ASCII
Таблица ASCII появилась в 1963 году. В ней 128 позиций (коды 0-127), из них управляющих — 33: диапазон 0x00-0x1F (первые 32 кода) плюс 0x7F (DEL, забой). Остальные 95 позиций — печатные символы: пробел, цифры, латиница, знаки.
Исторически эти коды управляли не экраном, а телетайпами и терминалами: они переключали режимы передачи, двигали печатающую головку, звонили в звонок. Вводили их с клавишей Ctrl — отсюда запись вида Ctrl+G для кода 7. Сегодня большинство управляющих кодов ASCII вживую не используется; на практике из них остаются перевод строки, возврат каретки, табуляция и реже — забой и нулевой символ.
Ключевые управляющие символы, которые реально встречаются в коде:
| Код (dec) | Код (hex) | Имя | Escape | За что отвечает |
|---|---|---|---|---|
| 0 | 0x00 | NULL | \0 |
нулевой символ, в C — конец строки |
| 7 | 0x07 | BEL | \a |
звуковой сигнал терминала |
| 8 | 0x08 | BS | \b |
забой — сдвиг на один символ назад |
| 9 | 0x09 | HT | \t |
горизонтальная табуляция |
| 10 | 0x0A | LF | \n |
перевод строки (line feed) |
| 11 | 0x0B | VT | \v |
вертикальная табуляция |
| 12 | 0x0C | FF | \f |
подача страницы (form feed) |
| 13 | 0x0D | CR | \r |
возврат каретки (carriage return) |
| 127 | 0x7F | DEL | нет | забой (исторически — стирание) |
Escape-последовательности \n, \t и прочие — универсальны: одинаково работают в Python, C, C++, Java и JavaScript, потому что все они опираются на те же коды ASCII. Отдельно стоят escape для печатных знаков, которые иначе конфликтуют с синтаксисом: \\ дает обратный слеш, \" — двойную кавычку, \' — апостроф. Это не управляющие символы, а экранирование — способ вставить в строку знак, который иначе закрыл бы ее или начал бы новую последовательность.
Escape-последовательности на практике
Соберу минимальный рабочий пример, который можно скопировать и запустить. Он показывает четыре частых escape сразу:
print("Первая строка\nВторая строка") # \n разрывает строку
print("Имя\tВозраст\tГород") # \t выравнивает по табам
print("Путь: C:\\Users\\name") # \\ - буквальный обратный слеш
print("Он сказал: \"привет\"") # \" - кавычка внутри кавычек
print(len("\n"), len("\\n")) # длина: спецсимвол против двух знаков
Вывод:
Первая строка
Вторая строка
Имя Возраст Город
Путь: C:\Users\name
Он сказал: "привет"
1 2
Последняя строка — главное доказательство модели из первого раздела. "\n" в памяти это один символ (len равен 1), а "\\n" — два обычных знака: обратный слеш и буква n (len равен 2). То есть escape в исходнике и символ в памяти — разные вещи.
Теперь свяжу каждую escape-последовательность с ее кодом ASCII напрямую:
pairs = [("\t", "tab"), ("\n", "line feed"), ("\r", "carriage return"),
("\0", "null"), ("\a", "bell"), ("\b", "backspace")]
for ch, name in pairs:
print(f"{name:16} код {ord(ch):3d} hex 0x{ord(ch):02X}")
Вывод:
tab код 9 hex 0x09
line feed код 10 hex 0x0A
carriage return код 13 hex 0x0D
null код 0 hex 0x00
bell код 7 hex 0x07
backspace код 8 hex 0x08
Функция ord возвращает числовой код символа — и он совпадает со значениями из таблицы ASCII. Значит, \t, \n и другие — это именно записи управляющих кодов, а не отдельная магия языка.
Перевод строки против возврата каретки
Пара \n и \r путается чаще всего, а в исходной версии статьи они и вовсе были описаны наоборот. Разведу их точно.
\n(LF, код 10) — перевод строки: курсор идет на строку ниже.\r(CR, код 13) — возврат каретки: курсор идет в начало текущей строки, не опускаясь.
Название «возврат каретки» пришло от печатной машинки: каретка физически возвращалась влево. Отдельно \r сегодня применяют, чтобы перерисовать текущую строку в терминале — например, обновлять процент загрузки на месте, не плодя строки.
Разные операционные системы исторически кодируют конец строки по-разному: Unix и macOS — одним \n, Windows — парой \r\n. Из-за этого один и тот же текстовый файл может выглядеть по-разному. Python умеет разбирать оба варианта:
data = "строка1\r\nстрока2\nстрока3"
print("символов всего:", len(data))
print("строк:", len(data.splitlines()))
for i, line in enumerate(data.splitlines(), 1):
print(i, repr(line))
Вывод:
символов всего: 24
строк: 3
1 'строка1'
2 'строка2'
3 'строка3'
Всего 24 символа: три слова по 7 знаков, плюс \r\n (два символа) и \n (один). Метод splitlines понимает и \r\n, и одиночный \n, поэтому получилось ровно три строки без пустых. Функция repr показывает строку как в исходнике: невидимые символы отрисовываются как escape, поэтому repr — главный инструмент, когда надо увидеть скрытый управляющий символ.
Частая ошибка: пути Windows
Обратный слеш в строковом литерале начинает escape-последовательность. Из-за этого путь Windows, скопированный как есть, ломается. Показываю тройкой: неверно -> реальный вывод -> исправление.
Неверно — обычная строка с одинарными слешами:
bad = "C:\news\table.txt" # \n и \t тут превратились в спецсимволы
print(bad)
Реальный вывод (вместо пути — перенос строки и табуляция):
C:
ews able.txt
\n стал переводом строки, \t — табуляцией, и путь распался. Исправление — сырая строка (raw string) с префиксом r: в ней обратный слеш трактуется буквально.
good = r"C:\news\table.txt" # r-строка: слеш - обычный символ
print(good)
print("обратных слешей:", good.count("\\"))
Вывод:
C:\news\table.txt
обратных слешей: 2
Тот же эффект дает удвоение слеша ("C:\\news\\table.txt"), но для путей и регулярных выражений r-строки читаются проще. Важна граница: префикс r отключает обработку escape только в этом литерале, на уже существующие строки и на ввод пользователя он не влияет.
Выводы
- Управляющий символ — это невидимый символ ASCII (коды 0x00-0x1F и 0x7F, всего 33), который подает команду, а не рисует глиф.
- Управляющий символ, escape-последовательность и видимый символ — три разных вещи:
\nв исходнике это два печатных знака, но в памяти один символ с кодом 0x0A (len("\n")равен 1,len("\\n")равен 2). \n(LF, код 10) переводит строку,\r(CR, код 13) возвращает каретку в начало; концы строк по ОС различаются: Unix и macOS —\n, Windows —\r\n, аsplitlinesразбирает оба.- Escape-последовательности
\n,\tи прочие универсальны для Python, C, C++, Java и JavaScript, так как опираются на одни коды ASCII;ordвозвращает тот самый код. - Обратный слеш в обычной строке начинает escape и ломает пути Windows; лечится сырой строкой с префиксом
rили удвоением слеша.
Где это применяется и как освоить на практике
Управляющие символы и escape-последовательности встречаются в повседневных задачах: форматирование вывода в консоль табуляцией, разбор текстовых файлов и CSV с разными концами строк, чистка данных от невидимых символов, экранирование кавычек и слешей при сборке строк и запросов. Понимание того, что \n — это один символ с кодом 0x0A, а не «два знака», снимает целый класс ошибок с путями, переносами строк и длиной строк.
Освойте тему на практике
Если хочется освоить работу со строками, вводом-выводом и базовыми конструкциями Python системно и с практикой, посмотрите курс Python Basic. Оценить формат и уровень до старта помогают бесплатные открытые уроки Otus — живые занятия с преподавателями.
Смежные темы: Сериализация в программировании, Типизация в программировании.
FAQ
Управляющий символ и escape-последовательность — это одно и то же? Нет. Управляющий символ — невидимый символ в памяти (например, перевод строки, код 10). Escape-последовательность (\n) — способ записать его в исходном коде видимыми знаками. В памяти от \n остается один символ, а не два.
Почему \t дает разное число пробелов? Табуляция — это один символ, а не набор пробелов. Ширину табуляции задает то, что показывает текст: терминал, редактор или браузер выравнивают до ближайшей позиции табуляции (часто кратной 4 или 8), поэтому визуальный отступ зависит от настроек отображения, а не от строки.
Как увидеть управляющие символы в строке? В Python используйте repr(s) — невидимые символы он покажет как escape (\n, \t, \r). Для побайтового разбора помогает s.encode() и просмотр кодов через ord или в hex.



