string в C++: строки простыми словами
В стандартной библиотеке C++ std::string
является ключевым классом для работы со строками. Этот класс предоставляет разработчикам удобный способ управления и манипуляции строками, заменяя традиционные массивы символов. В этой статье мы рассмотрим основные аспекты std::string
и его возможности в C++.
Что такое строки (string) в C++
string
- это более удобная альтернатива строками в стиле C, которую можно использовать в C++. Внутреннее устройство string
похоже на вектор символов, мы можем изменять строку и ее размер на лету.
Давайте рассмотрим простой пример работы со строками в C++:
#include <iostream>
using namespace std;
int main() {
string greeting = "Привет"; // инициализация строки
string world("Мир"); // явный вызов конструктора
string exclamation{'!'}; // инициализация как массива символов
cout << greeting << " " << world << exclamation << endl;
return 0;
}
Вывод данной программы:
Привет Мир!
Теперь давайте разберем, что делает данная программа:
- в строке 6 мы присваиваем значение переменной типа
string
при помощи оператора=
. Этот вариант вы будете встречать наиболее часто. - в строке 7 мы явно вызываем конструктор
string
и передаем туда нужную нам строку. - в строке 8 мы используем тот факт, что строка работает как вектор символов, поэтому мы можем использовать конструкцию вида
{<элемент 1>, <элемент 2>, ...}
. - в строке 10 мы выводим строки на экран используя стандартный
cout
.
Теперь давайте рассмотрим операции, которые мы можем производить над строками.
Объединение строк (конкатенация)
Чтобы соединить две строки достаточно воспользоваться оператором +
:
string c = "С";
string pp = "++";
string cpp = c + pp;
cout << "cpp = " << cpp << endl;
Вывод программы:
cpp = C++
При этом не обязательно соединять значения из нескольких переменных. Мы можем объединить строку с C строкой "строка в формате C"
(массивом символов char[]
):
string c = "С";
string cpp = c + "++";
cout << "cpp = " << cpp << endl;
Нельзя соединить два строковых литерала
"C" + "++"
, поскольку оператор+
не определен на массивах типаchar[]
. Для того чтобы сложить две строки при помощи+
, обязательно на одной из сторон оператора+
должна находиться строкаstring
.
Вывод программы идентичен предыдущему:
cpp = C++
Помимо оператора +
, есть метод append
, который позволяет добавить одну строку к другой:
string lang = "С";
lang.append("++");
cout << "lang = " << lang << endl;
Вывод программы:
lang = C++
Отличие метода append
от +
заключается в том, что append
меняет существующую строку, в то время как +
создает новую.
Поскольку
append
меняет существующую строку, он работает быстрее чем+
особенно при многократных слияниях строк.
Числа и строки
Стоит отметить, что нельзя получить сумму чисел внутри строки при помощи оператора +
. Давайте рассмотрим пример:
string a = "12";
string b = "34";
cout << "a + b = " << a + b << endl;
Вывод:
a + b = 1234
Как вы видите, сложение просто добавило цифры одной строки в конец другой. Если мы попробуем сложить строку с числом, то получим ошибку компиляции. Код в следующем примере не скомпилируется:
string a = "12";
cout << a + 34 << endl; // Invalid operands to binary expression ('std::string' and 'int')
Что будет выведено на экран:
string a = "23";
string b = "45";
cout << a + b << endl;
Получение длины строки
Чтобы получить длину строки, мы можем воспользоваться методом length
:
string s = "C++";
cout << "s.length() = " << s.length() << endl;
Вывод:
s.length() = 3
У метода length
есть “брат-близнец” - size
:
string s = "C++";
cout << "s.size() = " << s.size() << endl;
Вывод:
s.size() = 3
Между ними нет разницы, поэтому вы можете выбрать название метода на свой вкус.
Получение и изменение символа в строке
string
позволяет нам получать любой символ по указанному индексу при помощи оператора []
. При этом можно также использовать метод at
, однако оператор []
является более компактным и встречается чаще в реальных программах:
string s = "ABCDE";
cout << "s[1] = " << s[1] << endl;
Первый символ в строке имеет индекс
0
.
Вывод:
s[1] = B
Так же, как и с массивами, мы можем присвоить любой ячейке новое значение:
string s = "ABCDE";
s[1] = 'X';
cout << "s[1] = " << s[1] << endl;
Вывод:
s[1] = X
Специальные символы
А как же нам объявить строку, которая состоит из двух линий? Для этого достаточно воспользоваться специальным символом \n
:
string s = "Первая строка.\nВторая строка";
cout << s << endl;
Вывод:
Первая строка.
Вторая строка
В C++ все специальные символы в строках начинаются с \
. Вот примеры часто используемых специальных символов:
\n
- перенос строки\'
- одинарная кавычка\"
- двойная кавычка\\
- обратный слеш
Что будет выведено на экран:
cout << "Привет, мир\\nПривет снова!" << endl;
Привет снова!
Ввод строк из консоли используя cin
cin
позволяет нам вводить строки напрямую из консоли. Для этого достаточно указать переменную типа string
в которую будет записана строка введенная пользователем:
string name;
cout << "Введите ваше имя: ";
cin >> name;
cout << "Ваше имя: " << name << endl;
Пример работы программы:
Введите ваше имя: Дима
Ваше имя: Дима
Однако, если мы попытаемся ввести строку с пробелом, то cin
считает строку только до первого пробела. Если мы хотим считать строку полностью, нужно использовать функцию getline
:
string name;
cout << "Введите ваше имя: ";
getline(cin, name);
cout << "Ваше имя: " << name << endl;
Пример работы программы:
Введите ваше имя: Вася Пупкин
Ваше имя: Вася Пупкин
Теперь давайте познакомимся подробнее с методами, которые есть у string
.
Методы для строк
Мы уже видели несколько методов: length
, size
и append
. Однако у строк есть еще много полезных функций, которые упростят вам жизнь:
- begin/end - получить итератор для строки
- empty - проверка на пустоту
- clear - очистка строки
- front/back - получить первый/последний символ
- insert - вставить подстроку
- erase - удалить подстроку
- replace - изменить подстроку
- find - найти подстроку
- compare - сравнить две строки
begin/end
string
— это контейнер в C++. Как и другие контейнеры в C++, он предоставляет возможность обхода своих элементов. Для этого можно использовать итераторы, получаемые с помощью методов begin
и end
:
string s = "123";
for (auto it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
Вывод данной программы:
1 2 3
Чтобы получить вывод
3 2 1
, нужно использовать методыrbegin
/rend
вместоbegin
/end
.
empty
Вместо того, чтобы писать s.length() == 0
, мы можем воспользоваться методом empty
:
string s = "";
cout << "s = " << (s.empty() ? "<пустая строка>" : s) << endl;
Вывод:
s = <пустая строка>
clear
Метод clear
позволяет нам очистить существующую строку:
string s = "Длинная строка";
cout << "s = " << s << endl;
s.clear();
cout << "s = " << (s.empty() ? "<пустая строка>" : s) << endl;
Вывод:
s = Длинная строка
s = <пустая строка>
front/back
Вместо обращения к индексам 0
и s.length() - 1
напрямую, можно воспользоваться методами front
и back
:
string s = "12345";
cout << "front = " << s.front() << endl;
cout << "back = " << s.back() << endl;
Вывод:
front = 1
back = 5
insert
Метод insert
позволяет нам добавить символы в любую часть существующей строки:
string s = "125";
s.insert(2, "34");
cout << "s = " << s << endl;
Вывод:
s = 12345
Первый аргумент метода insert
указывает, куда вставить. Второй аргумент - это подстрока, которую следует вставить по указанному индексу.
erase
Метод erase
удаляет часть строки:
string s = "123__45";
s.erase(3, 2);
cout << "s = " << s << endl;
Вывод:
s = 12345
erase
принимает два аргумента:
- позиция, с которой начинать удалять
- сколько символов нужно удалить
replace
Метод replace
является комбинацией методов erase
и insert
:
string s = "12__5";
s.replace(2, 2, "34");
cout << "s = " << s << endl;
Вывод:
s = 12345
Метод replace
принимает:
- позиция, с которой начинать замену
- количество символов, которые нужно заменить
- строка, на которую нужно заменить
find
Метод find
позволяет нам на йти подстроку в другой строке. Данный метод принимает строку, которую нужно найти. В случае если строку удалось найти, мы получим индекс первого вхождения данной подстроки. Если же подстроку найти не удалось, find
вернет -1
:
string s = "Не имей сто рублей, а имей сто друзей.";
int index = s.find("сто");
cout << "индекс первого вхождения \"сто\" = " << index << endl;
index = s.find("миллион");
cout << "index = " << index << endl;
Вывод данной программы:
индекс первого вхождения "сто" = 14
index = -1
Вас может удивить индекс вхождения подстроки “сто”. Все дело в том, что
string
хранит набор байт. Русские символы занимают два байта в отличии от пробела или цифр. Получается: “Не” - 4 байта, ” ” - 1 байт, “имей” - 8 байт, ” ” - 1 байт. В сумме - 14 байт. Вы можете подробнее почитать почему разные символы используют разное количество байт в статье про UTF-8.
Что будет выведено на экран:
string s = "Привет, мир!";
int index = s.find("мир");
cout << "index = " << index << endl;
compare
Закончим мы на методе compare
. Данный метод позволяет нам сравнить две строки и узнать, какая из них лексикографически больше. a.compare(b)
вернет:
-1
если a < b0
если a = b1
если a > b
Вот наглядный пример:
string a = "123";
string b = "43";
string c = "1234";
cout << "123.compare(123 ) = " << a.compare(a) << endl;
cout << "123.compare(43 ) = " << a.compare(b) << endl;
cout << "123.compare(1234) = " << a.compare(c) << endl;
cout << "43 .compare(1234) = " << b.compare(c) << endl;
Вывод:
123.compare(123 ) = 0
123.compare(43 ) = -1
123.compare(1234) = -1
43 .compare(1234) = 1
Если вывод вам кажется неправильным, я советую почитать подробнее про лексикографический порядок по ссылке выше.
Упражнения
- Использование
front
иback
:
Напишите программу, которая:- Запрашивает у пользователя строку.
- Используя методы
front
иback
, выводит на экран первый и последний символы этой строки.
- Редактирование строки:
Разработайте программу, которая:- Запрашивает у пользователя исходную строку.
- Предоставляет меню с 4 опциями:
insert
,erase
,replace
, иfind
. - В зависимости от выбора пользователя, программа предоставляет инструкции для использования соответствующего метода и выводит результат.
- Сравнение строк с помощью
compare
:
Напишите программу, которая:- Запрашивает у пользователя две строки.
- Использует метод
compare
для сравнения этих строк. - Выводит на экран результат сравнения (какая строка лексикографически больше, или если они равны).
Если хотите всегда быть в курсе последних новостей в мире программирования и IT, подписываетесь на мой Telegram-канал, где я делюсь свежими статьями, новостями и полезными советами. Буду рад видеть вас среди подписчиков!
Обсуждение