Урок №200. Строковые классы std::string и std::wstring

  Юрий  | 

  |

  Обновл. 15 Сен 2021  | 

 40810

 ǀ   4 

Стандартная библиотека 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 в наших примерах, всё это также применимо и к wstring.

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

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

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

  1. Rock:

    Скучная глава ибо тут чисто техническая информация которая полезна как справочник если подзабыл. Но в голове держать это тяжело да и не нужно скорее всего (10-15% полезного, остальное интуитивно понятно и не требует заучивания).

  2. Илья:

    Это ж юбилей,200 уроков и скоро,конец… интересное чувство….

  3. koh:

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

    1. koh:

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

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

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