Урок №200. std::string и std::wstring

  Юрий  | 

    | 

  Обновл. 16 Янв 2019  | 

 1523

 ǀ   2 

Стандартная библиотека C++ содержит много полезных классов, но одним из наиболее полезных является std::string. std::stringstd::wstring) — это строковый класс, который позволяет выполнять операции присваивания, сравнения и изменения строк. В следующих нескольких уроках мы подробно рассмотрим строковые классы стандартной библиотеки С++.

Примечание: Строки C-style обычно называют «строками C-style», тогда как std::string (и std::wstring) обычно называют просто «строками».

Зачем нужен std::string?

Мы уже знаем, что строки C-style используют массивы типа char для хранения целой строки. Если вы попытаетесь что-либо сделать со строками C-style, то вы очень быстро обнаружите, что работать с ними трудно, запутаться – легко, проводить отладку – сложно.

Строки C-style имеют много недостатков, в первую очередь связанных с тем, что вы должны самостоятельно управлять памятью. Например, если вы хотите поместить строку «Hello!» в буфер, то вам сначала нужно динамически выделить буфер правильной длины:

Не забудьте учесть дополнительный символ для нуль-терминатора! Затем вам нужно скопировать значение:

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

Не забудьте использовать версию delete, которая работает с массивами, а не обычную версию delete.

Кроме того, многие из интуитивно понятных операторов, которые предоставляет язык C для работы с числами, такие как =, ==, !=, <, >, >= и <= попросту не работают со строками C-style. Иногда они могут работать без ошибок со стороны компилятора, но результат будет неверным — например, сравнение двух строк C-style с использованием оператора == на самом деле выполнит сравнение указателей, а не строк. Присваивание одной строки C-style другой строке C-style, с использованием оператора =, будет работать, но выполняться будет копирование указателя (поверхностное копирование), что не всегда то, что нам нужно. Такие вещи могут легко привести к ошибкам и сбоям в программе, а разбираться с ними не так уж и легко (относительно)!

Суть в том, что работая со строками C-style вам нужно помнить множество придирчивых правил о том, что безопасно/небезопасно, запоминать много функций, таких как strcat() и strcmp(), чтобы использовать их вместо интуитивных операторов, а также выполнять управление памятью самостоятельно.

К счастью, C++ предоставляет гораздо лучший способ работы со строками: классы std::string и std::wstring. Используя такие концепции С++, как конструкторы, деструкторы и перегрузку операторов, std::string позволяет создавать и манипулировать строками в интуитивно понятной форме и, что не менее важно, выполнять это безопасно! Никакого управления памятью, запоминания странных названий функций и значительно меньшая вероятность возникновения ошибок/сбоев.

Класс std::string


Весь функционал класса std::string находится в заголовочном файле string:

На самом деле в заголовочном файле есть 3 разных строковых класса. Первый — это шаблон класса с именем basic_string<>, который является родительским классом:

Вы не будете работать с этим классом напрямую, так что не беспокойтесь о том, что такое traits или Allocator. Значений по умолчанию, которые присваиваются для этих объектов, будет достаточно почти во всех мыслимых и немыслимых случаях.

Дальше идут две разновидности basic_string<>:

Это те два класса, которые вы будете использовать. std::string используется для стандартных строк ASCII (кодировка UTF-8). std::wstring используется для строк Unicode (кодировка UTF-16). Встроенного класса для строк UTF-32 нет.

Хотя вы будете напрямую использовать std::string и std::wstring, весь функционал реализован в классе basic_string<>. string и wstring имеют доступ к этому функционалу напрямую. Следовательно, все функции ниже работают как со string, так и с wstring.

Функционал std::string

Создание и удаление:

   конструктор — создаёт или копирует строку;

   деструктор — уничтожает строку.

Размер и ёмкость:

   capacity() — возвращает количество символов, которое строка может хранить без дополнительного перевыделения памяти;

   empty() — возвращает логическое значение, указывающее, является ли строка пустой;

   length(), size() — возвращает количество символов в строке;

   max_size() — возвращает максимальный размер строки, который может быть выделен;

   reserve() — расширяет или уменьшает ёмкость строки.

Доступ к элементам:

   [], at() — доступ к элементу по заданному индексу.

Изменение:

   =, assign() — присваивает новое значение строке;

   +=, append(), push_back() — добавляет символы к концу строки;

   insert() — вставляет символы в произвольный индекс строки;

   clear() — удаляет все символы строки;

   erase() — удаляет символы по произвольному индексу строки;

   replace() — заменяет символы произвольных индексов строки другими символами;

   resize() — расширяет или уменьшает строку (удаляет или добавляет символы к концу строки);

   swap() — меняет местами значения двух строк.

Ввод/вывод:

   >>, getline() — считывает значения из входного потока в строку;

   << — записывает значение строки в выходной поток;

   c_str() — конвертирует строку в строку C-style с нуль-терминатором в конце;

   copy() — копирует содержимое строки (которое без нуль-терминатора) в массив типа char;

   data() — возвращает содержимое строки в виде массива типа char, который не заканчивается нуль-терминатором.

Сравнение строк:

   ==, != — сравнивает, являются ли две строки равными/неравными (возвращает bool);

   <, <=, >>= — сравнивает, являются ли две строки меньше или больше друг друга (возвращает bool);

   compare() — сравнивает, являются ли две строки равными/неравными (возвращает -1, 0 или 1).

Подстроки и конкатенация:

   + — соединяет две строки;

   substr() — возвращает подстроку.

Поиск:

   find — ищет индекс первого символа/подстроки;

   find_first_of — ищет индекс первого символа из набора символов;

   find_first_not_of — ищет индекс первого символа не из набора символов;

   find_last_of — ищет индекс последнего символа из набора символов;

   find_last_not_of — ищет индекс последнего символа не из набора символов;

   rfind — ищет индекс последнего символа/подстроки.

Поддержка итераторов и распределителей (allocators):

   begin(), end() — возвращает «прямой» итератор, указывающий на первый и последний (элемент, который идёт за последним) элементы строки;

   get_allocator() — возвращает распределитель;

   rbegin(), rend() — возвращает «обратный» итератор, указывающий на последний (т.е. «обратное» начало) и первый (элементы, который предшествует первому элементу строки, «обратный» конец) элементы строки. Отличие от begin() и end() в том, что движение итераторов происходит в обратную сторону.

Заключение


Вот и весь функционал std::string. Большинство из этих функций имеют несколько разновидностей для обработки разных типов входных данных – об этом мы ещё поговорим.

Хотя функционал достаточно широк, всё же есть несколько заметных упущений:

   поддержка регулярных выражений;

   конструкторы для создания строк из чисел;

   прописные/строчные функции;

   токенизация/разбиение строк на массивы;

   простые функции для получения левой или правой части строки;

   обрезка пробелов;

   конвертация из UTF-8 в UTF-16 и наоборот.

Всё, что перечислено выше, вам придётся реализовывать самостоятельно, либо конвертировать вашу строку в строку C-style (используя c_str()) и тогда уже использовать функционал, который предлагает язык C.

В следующих уроках мы рассмотрим функции класса string более подробно.

Примечение: Хотя мы используем string в наших примерах, всё одинаково применимо и к wstring.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (15 оценок, среднее: 5,00 из 5)
Загрузка...

Комментариев: 2

  1. Аватар koh:

    конструкторы для создания строк из чисел;
    to_string и to_wstring (C++ 11) позволяют получить строку из числа. добавьте пожалуйста)

    1. Аватар koh:

      + stol stoll для получения числа из строки

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *