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 = 5insert
Метод 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 = 12345erase принимает два аргумента:
- позиция, с которой начинать удалять
- сколько символов нужно удалить
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-канал, где я делюсь свежими статьями, новостями и полезными советами. Буду рад видеть вас среди подписчиков!
Обсуждение