Работа с функциями обработки символов и строк

Цель:

1. Освоить технику использования символьных и строковых данных в языке С++.

2. Научиться использовать библиотечные функции для работы с символами и стро­ками.

1. Работа с символами

Алфавит языка С++ определяется следующим набором правил:

буква::= az | AZ | _ (подчеркивание)[1];

восьмеричная цифра::= 07;

десятичная цифра::= 09;

шестнадцатиричная цифра::= десятичная цифра | (af | AF);

символ пунктуации::=.|«,»|: | «;»|?|!(акцент)| (апостроф) | " (кавычка);

скобка::=(«(»|«)»)(круглые скобки) |(«[» | «]»)(квадратные скобки) |(«{» |«}»)(фигурные скобки) |

(< | >)(угловые скобки);

знак::=-| +;

специальный символ::= ~ (тильда) | # (хэш или шарп) | % | ^ (карэт) | & (амперсенд) | * |«|»(пайп) |

/ (слэш) | \ (бэкслэш) | = | ð (пробел)| [ $ (бакс) ];

управляющий символ::=
\a
(тревога) | \b (возврат на предыдущую позицию) | \f (переход на новую страницу) | \n (переход на новую строку) |

\r (возврат каретки) | \t (горизонтальная табуляция) | \v (вертикальная табуляция) | ((0x | 0X) 01F | 7F9F);

символ алфавита::= буква | десятичная цифра | символ пунктуации | скобка | знак |

специальный символ | управляющий символ;

символ UNICODE::= [ \u | \U ](0000FFFF, [ 0000FFFF ]);

Символы алфавитов большинства европейских языков могут быть представлены в стандарте кодирования ASCII кодами в виде однобайтовых чисел (т.е. кодами в диапазоне 0… 255). При этом первая половина кодов (0…128) отводится для символов базового набора: специальных символов, латинских заглавных и строчных букв, арабских цифр и символов пунктуации.

В С печатаемыми символами являются те, которые можно отобразить на терминале. В ASCII-средах они расположены между пробелом (0x20) и тильдой (OxFE). Управляющие символы имеют значения, лежащие в диапазоне между нулем и Ox1F; в ASCII-средах к ним также относится символ DEL (0x7F).

Вторая половина кодов (128…255) отводится под буквы того или иного национального алфавита. Фактически, вторая половина кодовой таблицы интерпретируется по-разному, в зависимости от того, какой язык считается текущим. Однако для таких языков, как китайский, японский и некоторые другие, одного байта для кодирования символа недостаточно – алфавиты этих языков насчитывают более 255 символов. Решением этой проблемы стало создание стандарта кодирования UNICODE, позволяющего представить символы практически всех письменных языков многобайтовыми числовыми кодами. Стандарт UNICODE описывает универсальный набор символов и семейство кодировок, между которыми установлено взаимнооднозначное соответствие. Коды символов разделены на несколько областей. Область с кодами 0000007F содержит символы ASCII. Далее расположены области символов различных письменностей, символов пунктуации и технических символов. Часть кодов зарезервирована для использования в будущем. Под символы кириллицы выделены области кодов: 0400052F, 2DE02DFF, A640A69F.

Разновидности символьных типов данных определяются правилами:

базовый тип::= char (символьный)

модифицированный символьный тип::=

([ signed (знаковый)] | unsigned (беззнаковый)), (char | wchar_t (широкий));

Данные типа char хранятся в памяти в виде кодов символов (целых чисел), в формате данных типа int, а потому могут иметь знак.

В 1995 году в стандарт С++ был добавлен ряд функций, предназначенных для обработки двухбайтовых (т.н широких) символов UNICODE. Эти функции работают с символами типа wchar_t длиной 16 бит. Детали реализации типа wchar_t зависят от компилятора; при этом может изменяться и количество байтов, которое отводится под код одного символа. Тем не менее, в большинстве случаев используется именно двухбайтовое представление символов.

В языке С++ функции, предназначенные для работы с двухбайтовыми символами, используют два заголовочных файла: <wchar.h> и <wctype.h>. В заголовочном файле <wctype.h> определены типы wint_t, wctrans_t и wctype_t. Многие функции, предназначенные для работы с двухбайтовыми символами, принимают в качестве параметра двухбайтовый символ типа wint_t. Типы wctrans_t и wctype_t — это типы объектов, используемые для преобразования символов и определения категории символа соответственно. Кроме того, в заголовочном файле <wctype.h> определен двухбайтовый признак конца файла (EOF) с именем WEOF. Помимо win_t, в заголовочном файле <wchar.h> определены такие типы, как wchar_t, size_t и mbstate_t. Тип wchar_t создает двухбайтовый символ-объект, a size_t — это тип значения, возвращаемого оператором sizeof. Тип mbstate_t описывает объект, который хранит состояние преобразования многобайтового объекта в двухбайтовые символы. Заголовочный файл <wchar.h> также определяет макросы NULL, WEOF, WCHAR_MAX и WCHAR_MIN. Последние два макроса определяют максимальное и минимальное значения, которые могут храниться в объекте типа wchar_t.

До­пу­стимый диапазон значений символьных данных различных типов приведен в таблице 3.1.

Таблица 3.1

Тип данного Размер (в байтах) Диапазон значений (IA32)
[signed] char   -128 … 127
unsigned char   0 … 255
[signed] wchar_t   -32 768 … 32 767
unsigned wchar_t   0 … 65 535

Постоянная символьного типа определяется правилами:

символ национального алфавита::=

А | а | Б | б | В | в | Г || г | Ґ | ґ | Д | д | Е | е | Є | є | Ж | ж | З | з | И | и | І | і | Ї | ї | Й | й | К | к | Л | л | М | м | Н | н |

О | о | П | п | Р | р | С | с | Т | т | У | у | Ф | ф | Х | х | Ц | ц | Ч | ч | Ш | ш | Щ | щ | Ь | ь | Ю | ю | Я | я;

escape-последовательность(рис. 4.1)::=

одиночная escape-последовательность |

восьмеричная escape-последовательность |

шестнадцатиричная escape-последовательность;

одиночная escape-последовательность::= \’ | \” | \? | \\ | \a | \b | \f | \n | \r | \t | \v;

восьмеричная escape-последовательность::=

«\», восьмеричная цифра, [ восьмеричная цифра, [ восьмеричная цифра ] ];

шестнадцатиричная escape-последовательность::=(\x | \X), шестнадцатиричная

цифра, [ шестнадцатиричная цифра, [ шестнадцатиричная цифра ] ];

постоянная символьного типа::=

[L], «‘», ({ символ алфавита | символ национального алфавита |
escape-последовательность | символ UNICODE [2] | }), «‘»;

Если символьная постоянная содержит один символ, то она считается данным типа char, в противном случае – данным типа int. Если запись постоянной начинается с префикса «L», то она считается данным типа wchar_t («широкий символ»). Примеры постоянных символьного типа: ‘A’, ‘i’, ‘\n’, L’\x004d’ (символ ‘M’).

Стандартная библиотека языка С обладает богатым и разнообразным набором функций для обработки строк и символов. В языке С для работы с символьными функциями — используется заголовочный файл <ctype.h>.

Исторически сложилось так, что аргументами символьных функций являются целые значения, из которых используется только младший байт. Символьные функции автоматически преобразуют свои аргументы в тип unsigned char. Безусловно, эти функции можно вызывать с символьными аргументами, поскольку в момент вызова функции символы автоматически преобразуются к целому типу.

В таблице 3.2 описаны функции, которые работают с символами типа char. Эти функции были определены стандартом С++ и поддерживаются большинством компиляторов. Функции с префиксом is проверяют предъявляемый в качестве параметра символ на соответствие той или иной группе и возвращают, соответственно, результат 1 или 0, который можно интерпретировать как логический. Функции с префиксом to каким-либо образом преобразовывают предъявляемый в качестве параметра символ.

Таблица 3.2

Прототип функции Краткое описание функции
int isalnum(int с) возвращает 1, если с — код буквы или цифры (A...Z, a...z, 0...9), и 0 - в противном случае
int isalpha(int с) возвращает 1, если с — код буквы (A...Z, a...z), и 0 — в противном случае
int isascii (int с) возвращает 1, если с — код ASCII, т. е.принимает значение от 0 до 127, в противном случае — 0
int isblank(int c) возвращает 1, если c является символом, для которого функция isspace() возвращает значение 1; этот символ используется в качестве разделителя слов (так, для английского языка пробельными символами являются пробел и символ горизонтальной табуляции)
int iscntrl (int с) возвращает 1, если с — управляющий символ с кодами 0x00... 0x01F или 0x7F, и 0 — в противном случае
int isdigit(int с) возвращает 1, если с — цифра (0... 9) в коде ASCII, и 0 — в противном случае
int isgraph (int с) возвращает 1, если с — видимый (изображаемый) символ с кодом (0x21...0х7Е), и 0 — в противном случае
int islower(int с) возвращает 1, если с — код символа на нижнем регистре (a...z), и 0 — в противном случае
int isprint(int с) возвращает 1, если с — печатный символ с кодом (0x20... 0х7Е), и 0 — в противном случае
int ispunct(int с) возвращает 1, если с — символ-разделитель (соответствует iscntrl или isspace), и 0 — в противном случае
int isspace(int с) возвращает 1, если с — обобщенный пробел: пробел, символ табуляции, символ новой строки или новой страницы, символ возврата каретки (Ох09...Ox0D, 0x20), и 0 — в противном случае
int isupper(int с) возвращает 1, если с — код символа на верхнем регистре (A...Z), и 0 — в противном cлучае
int isxdigit(int с) возвращает 1, если с — код шестнадцатеричной цифры (0...9, A...F, a...f), и 0 — в противном случае
int toascii(int с) преобразует целое число с в символ кода ASCII, обнуляя все биты, кроме младших семи; результат от 0 до 127
int tolower(int с) преобразует код буквы с к нижнему регистру
int toupper(int с) преобразует код буквы с к верхнему регистру

Пример:

#include <ctype.h>

#include <stdio.h>

int main (void)

{ char ch;

for(;;) {

ch = getc (stdin);

if (ch = = '.') break;

if (isalnum(ch))

printf ("Символ %c является алфавитно - цифровым\n", ch);

}

return 0;

}

Ниже описаны функции, которые работают с двухбайтовыми символами типа wchar_t. Заголовок <wctype.h> содержит прототипы тех функций, которые позволяют классифицировать двухбайтовые символы. Эти функции распределяют по категориям двухбайтовые символы или преобразуют регистр буквенного символа, устанавливая строчное или прописное написание. Для большинства этих функций существуют эквивалентные им функции, работающие с символами типа char. Например, функция iswspace() для обработки двухбайтовых символов является версией функции isspace(). В целом, имена функций для обработки двухбайтовых символов образованы из имен аналогичных функций для работы с символами типа char путем добавления буквы «w». В таблице 3.3 приведены списки этих функций, а также соответствующие им функции для работы с символами типа char, которые были описаны выше.

Таблица 3.3

Прототип функции Соотвествующая функция для аргумента типа char
int iswalnum(wint_t ch) isalnum()
int iswalpha(wint_t ch) isalpha()
int iswblank(wint_t ch) isblank()
int iswcntrl(wint_t ch) iscntri()
int iswdigit(wint_t ch) isdigit()
int iswgraph(wint_t ch) isgraph()
int iswlower(wint_t ch) islowert()
int iswprint(wint_t ch) isprintt()
int iswpunct(wint_t ch) ispunct()
int iswspace(wint_t ch) isspacet()
int iswupper(wint_t ch) isupper()
int iswxdigit(wint_t ch) isxdigit()
wint_t towlower(wint_t ch) tolower()
wint_t towupper(wint_t ch) toupper()

Помимо функций, приведенных в таблице 3.3, в заголовочном файле < wctype.h> определены следующие функции, которые предоставляют открытые средства классификации символов.

wctype_t wctype (const char *attr);int iswctype (wint_t ch, wctype_t attr_ob);

Функция wctype() возвращает значение, которое можно передать функции iswctype() в качестве параметра attr_ob. Строка, адресуемая параметром attr, задает свойство, которое должен иметь символ. Это значение можно затем использовать для определения, является ли ch символом, который обладает этим свойством. Если является, то функция iswctype() возвращает 1; в противном случае возвращается 0. В любых условиях выполнения программы определены следующие строки свойств:

alnum digit print upperalpha graph punct xdigitcntrl lower space blank

Пример:

wctype_t x;x = wctype("space");if (iswctype(L' ', x)) printf("Это пробел.\n");

Кроме того, определены функции wctrans() и towctrans():

wctrans_t wctrans (const char *mapping);wint_t towctrans (wint_t ch, wctrans_t mapping_ob);

Функция wctrans() возвращает значение, которое можно передать функции towctrans() в качестве параметра mapping_ob. Строка, адресуемая параметром mapping, определяет отображение одного символа на другой. Данная строка затем может быть использована функцией towctrans() для преобразования символа ch. Функция возвращает преобразованное значение. При всех условиях выполнения программы поддерживаются следующие строки преобразования tolower и toupper.

Пример:

wctrans_t x;x = wctrans("tolower");wchar_t ch = towctrans(L'W', x);

printf("%c", (char) ch); // выводит w в нижнем регистре

2. Работа со строками

Стандартная библиотека языка С++ обладает также богатым и разнообразным набором функций для обработки строк.

Постоянная строкового типа определяется правилами:

постоянная строкового типа::=

[ L ], { ", { символ алфавита | символ национального алфавита |
escape-последовательность | символ UNICODE }, " };

Если запись постоянной начинается с префикса «L», то все символы строки считаются данными типа wchar_t («широкий символ»), в противном случае - данными типа char. Длина построянной строкового типа на 1 больше количества записанных в ней символов, поскольку транслятор добавляет в конец такой константы нуль-терминатор «\0» как признак окончания строки (рисунок 3.1).

 
 


Рисунок 3.1

Две постоянных строкового типа, записанные под­ряд, автоматически объединяются в одну (например, " Здравствуй," " мир! " преобразовывается в " Здравствуй, мир! ". Постоянную строкового типа можно записывать в нескольких смежных строках, разделяя строки символом «\», например, так:

“Добридень. \


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: