Коды ASCII символов
Управляющие символы (большинство непечатные; наиболее важные подсвечены жёлтым)
Печатные символы (стандартные)
| Символ | Dec | Hex | Oct | Описание |
|---|---|---|---|---|
| 32 | 20 | 040 | Пробел | |
| ! | 33 | 21 | 041 | Восклицательный знак |
| « | 34 | 22 | 042 | Кавычка (» в HTML) |
| # | 35 | 23 | 043 | Решётка (знак числа) |
| $ | 36 | 24 | 044 | Доллар |
| % | 37 | 25 | 045 | Проценты |
| & | 38 | 26 | 046 | Амперсанд |
| ‘ | 39 | 27 | 047 | Закрывающая одиночная кавычка (апостроф) |
| ( | 40 | 28 | 050 | Открывающая скобка |
| ) | 41 | 29 | 051 | Закрывающая скобка |
| * | 42 | 2a | 052 | Звёздочка, умножение |
| + | 43 | 2b | 053 | Плюс |
| , | 44 | 2c | 054 | Запятая |
| — | 45 | 2d | 055 | Дефис, минус |
| . | 46 | 2e | 056 | Точка |
| / | 47 | 2f | 057 | Наклонная черта (слеш, деление) |
| 0 | 48 | 30 | 060 | Ноль |
| 1 | 49 | 31 | 061 | Один |
| 2 | 50 | 32 | 062 | Два |
| 3 | 51 | 33 | 063 | Три |
| 4 | 52 | 34 | 064 | Четыре |
| 5 | 53 | 35 | 065 | Пять |
| 6 | 54 | 36 | 066 | Шесть |
| 7 | 55 | 37 | 067 | Семь |
| 8 | 56 | 38 | 070 | Восемь |
| 9 | 57 | 39 | 071 | Девять |
| : | 58 | 3a | 072 | Двоеточие |
| ; | 59 | 3b | 073 | Точка с запятой |
| 62 | 3e | 076 | Знак больше | |
| ? | 63 | 3f | 077 | Знак вопроса |
| @ | 64 | 40 | 100 | эт, собака |
| A | 65 | 41 | 101 | Заглавная A |
| B | 66 | 42 | 102 | Заглавная B |
| C | 67 | 43 | 103 | Заглавная C |
| D | 68 | 44 | 104 | Заглавная D |
| E | 69 | 45 | 105 | Заглавная E |
| F | 70 | 46 | 106 | Заглавная F |
| G | 71 | 47 | 107 | Заглавная G |
| H | 72 | 48 | 110 | Заглавная H |
| I | 73 | 49 | 111 | Заглавная I |
| J | 74 | 4a | 112 | Заглавная J |
| K | 75 | 4b | 113 | Заглавная K |
| L | 76 | 4c | 114 | Заглавная L |
| M | 77 | 4d | 115 | Заглавная M |
| N | 78 | 4e | 116 | Заглавная N |
| O | 79 | 4f | 117 | Заглавная O |
| P | 80 | 50 | 120 | Заглавная P |
| Q | 81 | 51 | 121 | Заглавная Q |
| R | 82 | 52 | 122 | Заглавная R |
| S | 83 | 53 | 123 | Заглавная S |
| T | 84 | 54 | 124 | Заглавная T |
| U | 85 | 55 | 125 | Заглавная U |
| V | 86 | 56 | 126 | Заглавная V |
| W | 87 | 57 | 127 | Заглавная W |
| X | 88 | 58 | 130 | Заглавная X |
| Y | 89 | 59 | 131 | Заглавная Y |
| Z | 90 | 5a | 132 | Заглавная Z |
| [ | 91 | 5b | 133 | Открывающая квадратная скобка |
| \ | 92 | 5c | 134 | Обратная наклонная черта (обратный слеш) |
| ] | 93 | 5d | 135 | Закрывающая квадратная скобка |
| ^ | 94 | 5e | 136 | Циркумфлекс, возведение в степень, знак вставки |
| _ | 95 | 5f | 137 | Нижнее подчёркивание |
| ` | 96 | 60 | 140 | Открывающая одиночная кавычка, гравис, знак ударения |
| a | 97 | 61 | 141 | Строчная a |
| b | 98 | 62 | 142 | Строчная b |
| c | 99 | 63 | 143 | Строчная c |
| d | 100 | 64 | 144 | Строчная d |
| e | 101 | 65 | 145 | Строчная e |
| f | 102 | 66 | 146 | Строчная f |
| g | 103 | 67 | 147 | Строчная g |
| h | 104 | 68 | 150 | Строчная h |
| i | 105 | 69 | 151 | Строчная i |
| j | 106 | 6a | 152 | Строчная j |
| k | 107 | 6b | 153 | Строчная k |
| l | 108 | 6c | 154 | Строчная l |
| m | 109 | 6d | 155 | Строчная m |
| n | 110 | 6e | 156 | Строчная n |
| o | 111 | 6f | 157 | Строчная o |
| p | 112 | 70 | 160 | Строчная p |
| q | 113 | 71 | 161 | Строчная q |
| r | 114 | 72 | 162 | Строчная r |
| s | 115 | 73 | 163 | Строчная s |
| t | 116 | 74 | 164 | Строчная t |
| u | 117 | 75 | 165 | Строчная u |
| v | 118 | 76 | 166 | Строчная v |
| w | 119 | 77 | 167 | Строчная w |
| x | 120 | 78 | 170 | Строчная x |
| y | 121 | 79 | 171 | Строчная y |
| z | 122 | 7a | 172 | Строчная z |
| < | 123 | 7b | 173 | Открывающая фигурная скобка |
| | | 124 | 7c | 174 | Вертикальная черта |
| > | 125 | 7d | 175 | Закрывающая фигурная скобка |
| 126 | 7e | 176 | Тильда (приблизительно) |
Расширенный набор символов (ANSI) в русской кодировке Win-1251
Перевод строки
Перевод строки, или разрыв строки — продолжение печати текста с новой строки, то есть с левого края на строку ниже, или уже на следующей странице.
Разделителем строк, обозначающим место перевода строки, в текстовых данных служит один или пара управляющих символов, а в размеченном тексте также — определённый тег (в HTML — тег
, от англ. break — «разрыв»). Разделитель строк также называют просто переводом строки, когда нет надобности их различать.
Вместе с другими действиями перевод строки выполняется также перед следующим абзацем или страницей.
Содержание
Терминология
Таким образом, вывод последовательности CR+LF в семантике терминала гарантирует действие «создание новой строки».
Терминалы (и их эмуляторы) могут также проводить различные преобразования символов (например, LF → CR+LF, CR → CR+LF) при вводе и выводе текста.
Жёсткий возврат, иногда аппаратный возврат — разделитель строк, поставленный пользователем.
Мягкий возврат — перевод строки, выполненный текстовым процессором в том месте текста, которое им выбрано. Мягкий возврат является разделителем строк для текстового процессора и не является таковым для пользователя.
В ASCII
Системы, основанные на ASCII или совместимом наборе символов, используют или LF (перевод строки, 0x0A), или CR (возврат каретки, 0x0D) по отдельности, или последовательность CR+LF; см. ниже историческую причину для соглашения CR+LF. Эти названия основаны на командах принтера: перевод строки означает, что одна строка на бумаге должна быть перенесена при печати, а возврат каретки означает, что каретка печатающего устройства должна вернуться к началу текущей строки.
В Юникоде
По стандарту, любое совместимое с Юникодом приложение должно воспринимать как перевод строки каждый из нижеследующих символов:
Трудности
Нет общепринятых сокращений русских терминов. ВК (Возврат Каретки) совпадает по написанию с сокращением от англ. BreaK («разрыв [строки]», — то же, что перевод строки), а ПС не различает Подачу Строки и Перевод Строки.
Разница представлений
Перевод строки при вводе с клавиатуры представлен единообразно во всех системах — символом CR, и в системах с другим представлением перевода строки текстовые данные приходится перекодировать.
Последняя строка
История
На перфокартных системах хранения данных одна строка записывалась на одну перфокарту, поэтому строка была заданной длины, по количеству колонок (обычно 80). Строки короче добивались пробелами, а строки длиннее обрезались. Разделителя строк не было, а неявный перевод строки предполагался через каждые 80 символов. Некоторые ранние мейнфреймовые операционные системы переняли это для хранения текста в файлах, где уже не было естественного ограничения на длину строки.
На механических пишущих машинках был рычаг, который возвращал каретку к левому краю страницы и прокручивал вал, подвигая бумагу вверх на строку. На телетайпах и более поздних алфавитно-цифровых печатающих устройствах (АЦПУ) вместо каретки была головка, в лазерных принтерах она перестала быть материальной, но в термине возврат каретки всё это продолжали называть кареткой, чтобы его не менять. На телетайпах возврат каретки и подачу строки разделили, откуда традиция представления перевода строки как CR+LF перешла и к текстовым файлам.
Конец строки
Телетайпы сначала печатали на рулонной бумаге, и сообщения начинали и заканчивали переводом строки, чтобы каждое начиналось с новой строки наверняка. Отсюда пошёл обычай включать разделитель сообщений в состав самого сообщения.
На компьютерах появился диалоговый режим работы, когда поочерёдно печатались вводимые управляющие сообщения пользователя и ответные программные сообщения. Пользователь после сообщения всегда переводил строку, так как одновременно это означало команду к исполнению, а вот программы после своего сообщения строку иногда не переводили, несмотря на предписание. Устройство вывода изначально не было приспособлено к тому, чтобы терминал мог следить за переводами строк, и реализовать это было трудно, поэтому чтобы ввод пользователя начинался с новой строки наверняка, управляющий диалогом терминал после программного сообщения переводил строку тоже. Помещать перевод строки предписывалось и в конце текстового файла.
Забота о разделении сообщений легла на терминал, и думать об этом перестали, а перевод строки в конце текста переосмыслился как конец последней строки, вместе с чем как концы строк переосмыслились и вообще все переводы строк, чему способствовало удобство работы с регулярно завершёнными строками с точки зрения программирования, сродни нуль-терминированным строкам. Так обычай включать разделитель сообщений в состав сообщения перешёл в обычай включать разделитель строк в состав строки.
Лишняя строка в конце файла обычно не представляет хлопот, поэтому перевод строки до сих пор называют концом строки, а разделитель строк — символом конца строки (EOL, англ. end of line ).
Перетекание разделителя в завершитель и обратно бывает не только у перевода строки. Так, точка с запятой в языке Си команды завершает, а в Паскале их разделяет. В письменной речи после нескольких предложений точку почти всегда ставят, а после одиночного — чаще нет. Это колебание хорошо видно в списках, где одиночные предложения иногда начинают с большой буквы, а иногда — с маленькой.
Абзац
На телетайпах, а потом и в первых редакторах разделение текста на абзацы не имело своего особого представления, для этого использовали пустые строки или отступ из нескольких пробелов, а переводы строки внутри абзаца проставляли вручную.
Позже в редакторах появился автоматический перенос, выполняемый на лету при отрисовке текста каждый раз заново. Для отличения от ручного его назвали мягким возвратом, а ручной — жёстким (перенос называли и просто возвратом, см. раздел Разница представлений). Разделитель строк при этом переносил как раньше, но приобрёл смысл ещё и разделителя абзацев — для тех строк, в которых срабатывал автоперенос и которые становились при этом абзацами. Включатель такого режима назвали переносом по словам (англ. word wrap ). При автопереносе ручной перенос разрывал абзац, межабзацный интервал делался как раньше (в новых терминах — перемежением пустым абзацем), но основное качество абзаца — независимость от разбиения на строки — было достигнуто.
Режим автопереноса включался и выключался пользователем вручную, определить это программно было трудно, то есть, избавившись от ручного переноса, получили другую ручную операцию. Стало понятно, что не обойтись без более автоматизирующего разнесения разделителя строк и разделителя абзацев, то есть для них понадобились два разных символа.
Чтобы не заботиться о совместимости с уже существующим в ASCII разделителем строк/абзацев, разработчики не стали использовать символы ASCII для разделителя строк и разделителя абзацев. В HTML использовали теги
и
, в Юникоде — символы U+2028 и U+2029, соответственно. В Википедии абзацы можно разделять пустыми строками, отображаемыми при этом полноценным интервалом.
Код символа перевода каретки
Любой язык программирования содержит средства представления и обработки текстовой информации. Другое дело, что обычно программист наряду с символами имеет дело с типом данных (формой представления) – строкой, причем особенности ее организации скрыты, а для работы предоставлен стандартный набор функций. В Си, наоборот, форма представления строки является открытой, а программист работает с ней «на низком уровне».
Представление символов и строк в Си
Примечание. Исторически сложившееся «рыночное разнообразие» на момент появления стандарта привело к тому, что имеются несколько кодовых таблиц, представляющих кириллицу:
· работа с текстовыми файлами «вписана» в стандартный ввод-вывод. Например, в Си потоки ввода-вывода могут быть перенаправлены как на текстовый файл, так и на консольный ввод-вывод (клавиатура – экран);
· если приложения не работают с форматами данных друг друга (не совместимы по данным), то единственным форматом обмена является текстовый файл, в котором числовые (или символьные ) данные разделены стандартными разделителями (пробел, табуляция, запятая, точка с запятой, конец строки). Обмен данными через такие файлы называется экспортом-импортом. В Си файлы такого формата читаются стандартными функциями форматного ввода;
· многие приложения (компиляторы, серверные приложения) наряду с оконными интерфейсами имеют возможность работы в режиме командной строки и чтения управляющих (текстовых) командных файлов.
Константа Название Действие
\ a bel Звуковой сигнал
\b bs Курсор на одну позицию назад
\f ff Переход к началу (перевод формата)
\n lf Переход на одну строку вниз(перевод строки)
\r cr Возврат на первую позицию строки
\ t ht Переход к позиции, кратной 8 (табуляция)
\v vt Вертикальная табуляция по строкам
\nn Символ с восьмеричным кодом nn
\xnn Символ с шестнадцатеричным кодом nn
\0 Символ с кодом 0
Некоторые программы и стандартные функции обработки символов и строк (isdigit,isalpha) используют тот факт, что цифры, прописные и строчные (маленькие и большие) латинские буквы имеют упорядоченные по возрастанию значения кодов:
· строка хранится в массиве символов, массив символов может быть инициализирован строкой, а может быть заполнен программно:
· соответствие размерности массива и длины строки транслятором не контролируется, за это несет ответственность программа (программист, ее написавший):
char C[20], B []=”Строка слишком длинная для C ”;
// следить за переполнением массива
// и ограничить строку его размерностью
char A[80] = «123456\r\n»;
char B[] = «aaaaa\033bbbb»;
Функции стандартной библиотеки ввода-вывода обязаны «сглаживать противоречия», связанные с исторически сложившимися формами и анахронизмами в представлении строки в различных устройствах ввода-вывода и операционных системах (текстовый файл, клавиатура, экран) и приводить их к единому внутреннему формату.
Стандартные приемы обработки строк
· редактировать строку «на месте», реализуя вставку и удаление символов или фрагментов;
· организовать посимвольное переписывание входной строки в выходную, с копированием нужных и преобразованных фрагментов (что проще).
Получить символ десятичной цифры из значения целой переменной, лежащей в диапазоне 0..9:
int n; char c; c = n + ‘0’;
Получить символ шестнадцатеричной цифры из значения целой переменной, лежащей в диапазоне 0..15:
Получить значение целой переменной из символа десятичной цифры:
Получить значение целой переменной из шестнадцатеричной цифры:
Преобразовать маленькую латинскую букву в большую:
//— Подсчет количества слов
//— Удаление лишних пробелов при посимвольном переписывании
void nospace(char c1[],char c2[]) <
c 2[ j ++]=’ ‘; // добавить пробел
c 2[ j ++]= c 1[ i ]; // Перенести символ слова
//—- Сравнение строк по значениям кодов
int my_strcmp(unsigned char s1[],unsigned char s2[]) <
if (s1[n] == s2[n]) return 0;
//—- Сравнение строк с заданными «весами» символов
static char ORD[] = » АаБбВвГгДдЕе 1234567890″;
for ( int n=0; ORD[n]!=’\0′; n++)
int my_strcmp(char s1[],char s2[])<
if (c1 == c2) return 0;
Пример: a < b < c >b > a < d < e < g >e > d > a => < c >< b 1 b >< g >< e 3 e > < d 4 d >a 2 a 5 a
Задачу будем решать по частям. Несомненно, нам потребуется функция, которая ищет открывающуюся скобку для самого внутреннего вложенного фрагмента. Имея ее, можно организовать уже известное нам переписывание и «выкусывание». Основная идея алгоритма поиска состоит в использовании переменной-счетчика, которая увеличивает свое значение на 1 на каждую из открывающихся скобок и уменьшает на 1 на каждую из закрывающихся. При этом фиксируется максимальное значение счетчика и позиция элемента, где это происходит.
int i; // Индекс в строке
int k ; // Счетчик вложенности
int max ; // Максимум вложенности
int b; // Индекс максимальной » <"
for (i=0, max=0, b=-1; c[i]!=0; i++)<
Другой вариант: функция ищет первую внутреннюю пару скобок. Запоминается позиция открывающейся скобки, при обнаружении закрывающейся скобки возвращается индекс последней открывающейся. Заметим, что его также можно использовать, просто последовательность извлечения фрагментов будет другая.
int i; // Индекс в строке
int b; // Индекс максимальной » <"
Идея основного алгоритма заключается в последовательной нумерации «выкусываемых» из входной строки фрагментов, при этом на место каждого помещается его номер – значение счетчика, которое для этого переводится во внешнюю форму представления.
//—— Копирование вложенных фрагментов с » выкусыванием»
void copy(char c1[], char c2[])<
int i =0; // Индекс в выходной строке
int k ; // Индекс найденного фрагмента
int n ; // Запоминание начала фрагмента
int m ; // Счетчик фрагментов
for ( n = k ; c 1[ k ]!= ‘>’ ; k ++, i ++) c 2[ i ]= c 1[ k ]; // Переписать фрагмент и его «>»
if ( m /10!=0) c 1[ n ++] = m /10 + ‘0’ ; // На его место две цифры
c 1[ n ++] = m %10 + ‘0’ ; // номера во внешней форме
c 1[ n ]=0; > // сдвинуть » хвост» к началу
for ( k =0; c 1[ k ]!=0; k ++, i ++) c 2[ i ]= c 1[ k ]; // перенести остаток
c 2[ i ]=0;> // входной строки
Практический совет – желательно избегать сложные вычисления над индексами. Лучше всего для каждого фрагмента строки заводить свой индекс и перемещать их независимо друг от друга в нужные моменты. Что, например, сделано при «уплотнении» строки – индекс k после переписывания найденного фрагмента «останавливается» на начале «хвоста» строки, который переносится под индекс n – начало удаляемого фрагмента. Причем записываемые цифры номера смещают это начало на один или два символа. Таким образом, фрагмент заменяется во входной строке на его номер.
Внешняя и внутренняя форма представления чисел
Текст и числовые данные имеют еще одну точку соприкосновения. Дело в том, что все наблюдаемые нами числовые данные – это совсем не то, с чем имеет дело компьютер. При вводе или выводе целого или вещественного числа мы имеем дело со строкой текста, в которой присутствуют символы, изображающие цифры числа – внешней формой представления.
Функции и объекты стандартных потоков ввода/вывода могут, в частности, вводить и выводить целые числа, представленные в десятичной, восьмеричной и шестнадцатеричной системах счисления. При этом происходят преобразования, связанные с переходом от внешней формы представления к внутренней и наоборот.

Обратите внимание, что о системе счисления имеет смысл говорить только тогда, когда число рассматривается в виде последовательности цифр, то есть во внешней форме представления числа. Внутренняя форма представления числа – двоичная и нас, грубо говоря, не интересует, поскольку компьютер корректно оперирует с ней и без нашего участия.
На самом деле алгоритмы ввода-вывода числовых данных (вернее, преобразования данных из внешней формы во внутреннюю, и наоборот) идентичны алгоритмам преобразования чисел из произвольной системы счисления в десятичную (см. 1.3). При этом десятичная система играет роль внутренней («родной») формы представления.
Ввод целого числа сопровождается его преобразованием из внешней формы – последовательности цифр – в внутренней – целой переменной, которая «интегрирует» цифры в одно значение с учетом их веса (что зависит, кроме всего прочего, и от системы счисления, в которой представлено вводимое число). В преобразовании используется тот факт, что при добавлении к числу очередной цифры справа старое значение увеличивается в 10 раз и к нему добавляется значение новой цифры, например:
Значение: 123 1234 = 123 * 10 + 4
Тогда в основу алгоритма может быть положен цикл просмотра всех цифр числа слева направо, в котором значение числа на текущем шаге цикла получается умножением на 10 результата предыдущего цикла и добавлением значения очередной цифры:
//—— Ввод десятичного целого числа
int StringToInt(char c[])<
if (c[i]==’\0′) return 0; // Поиск первой цифры
for (n=0; c[i]>=’0′ && c[i] // Накопление целого
//—- Вывод целого десятичного числа
void IntToString(char c[], int n)
for (nn=n, k=0; nn!=0; k++, nn/=10); // Подсчет количества цифр числа
c[k] = ‘\0’; // Конец строки
for (k—; k >=0; k—, n /= 10) // Получение цифр числа
c[k] = n % 10 + ‘0’; // в обратном порядке
При преобразовании дробной части во внешнюю форму используется тот факт, что при умножении дробной части на 10 (точнее, на основание системы счисления) очередная цифра «вылезает» в целую часть. Из нее формируется символ, после чего целая часть отбрасывается.
//—- Вывод вещественного десятичного числа
void FloatToString(char c[], double v)
for (nn=v, k=0; nn!=0; k++, nn/=10); // Подсчет количества цифр
kk=k-1; c[k++] = ‘.’; // целой части числа
for (nn=v; kk >=0; kk—, nn /= 10) // Получение цифр числа
c[kk] = nn % 10 + ‘0’; // в обратном порядке
v-=(int)v; // Убрать целую часть
Фрагменты вывода целой и дробной частей «сшиваются» путем запоминания местонахождения в строке символа «точка», разделяющего целую и дробную части.
//—— Ввод десятичного вещественного числа
double StringToFloat(char c[])<
if (c[i]==’\0′) return 0; // Поиск первой цифры
for (n=0; c[i]>=’0′ && c[i] // Накопление целого
v=v/10; // весом разряда дробной части
Преобразование, в котором внешняя форма числа задана в другой системе счисления, выполняются аналогично, только вместо числа 10 используется основание системы, а для систем счисления, больших 10, используется особое преобразование символов-цифр во внутреннее представление:
Посимвольная и пословная обработка.
Одну и ту же программу обработки строки текста можно написать разными способами. Если речь идет о формате текстовой строки, то отслеживать его можно двумя способами (см. 3.8):
// Функция возвращает индекс начала слова или 1, если нет слов
// Логика переменной состояния – n – счетчик символов слова
if (s[i]!=’ ‘) n++; // символ слова увеличить счетчик
n=0; // фиксация максимального значения
>> // то же самое для последнего слова
// Структурная логика – 3 цикла: просмотр слов, пробелов и символов
while (in[i]==’ ‘) i++; // Пропуск пробелов перед словом
for (k=0;in[i]!=’ ‘ && in[i]!=0; i++,k++); // Подсчет длины слова
m=k; b=i-k; > // Одновременно запоминается
По завершении посимвольного просмотра строки последнее слово (если после него нет пробела) оказывается необработанным. Поэтому контекст фиксации максимума повторяется после выхода из цикла.
Здесь можно проиллюстрировать еще один принцип разработки программ: после ее написания для произвольной «усредненной» ситуации необходимо проверить ее «на крайности». В данном случае, при отсутствии в строке слов (строка состоит из пробелов или пуста), установленное начальное значение b =-1 будет возвращено в качестве результата (что и задумывалось при установке значения –1 как недопустимого).
Лабораторный практикум
1. В строке найти последовательности цифр, каждую из них считать числом в той системе счисления, которая соответствует максимальной цифре, заменить числа в строке символами с кодами, полученными из этих чисел. Пример: aaa 010101 bbb 343 ccc – двоичная и пятиричная системы счисления.
2. В строке найти последовательности цифр, каждую из них считать числом в той системе счисления, которая соответствует первой цифре, заменить числа в строке символами с кодами, полученными из этих чисел. Пример: aaa 2010101 bbb 8343 ccc – двоичная и восьмиричная системы счисления.
6. Найти в строке два одинаковых фрагмента (не включающих в себя пробелы) длиной более 5 символов, скопировать их в выходную строку и удалить. Повторять этот процесс, пока такие фрагменты находятся. Остаток строки добавить в выходную.
7. Найти во входной строке самую внутреннюю пару скобок <. >и переписать в выходную строку содержащиеся между ними символы. Во входной строке фрагмент удаляется. Повторять этот процесс, пока во входной строке не останется скобок, остаток также переписать в выходную строку.
10. Определить, является ли строка палиандромом (например, «я у ребят беру наган») – удалить пробелы, найти фрагменты – палиандромы максимальной длины и удалить.
Вопросы без ответов
Содержательно определите действие, производимое над строкой. Напишите вызов функции (входные неизменяемые строки могут быть представлены фактическими параметрами – строковыми константами).
