Строки в C++

Для работы со строками в C++ обычно используют тип std::string из заголовочного файла <string>.

#include <iostream>
#include <string>

using namespace std;

int main() {
    string s = "Hello";
}

Считывание строки

Оператор >> читает строку только до первого пробельного символа.

string s;
cin >> s;

Если нужно прочитать всю строку целиком, вместе с пробелами, используется getline.

string s;
getline(cin, s);

После чтения числа через cin >> в потоке остаётся конец строки. Если по формату ввода следующая строка должна читаться целиком через getline, остаток текущей строки сначала пропускают.

#include <limits>

int n;
cin >> n;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
getline(cin, s);

Чтение до конца файла

Если заранее неизвестно количество слов или строк, условием цикла можно сделать само чтение.

string word;
while (cin >> word) {
    // очередное слово
}

Аналогично можно читать текст построчно:

string line;
while (getline(cin, line)) {
    // очередная строка
}

Длина и символы строки

Количество символов возвращают методы size() и length(). Для std::string они делают одно и то же.

string s = "abcdef";

cout << s.size();    // 6
cout << s.length();  // 6

Символы нумеруются с нуля. К символу с индексом i можно обратиться как к элементу массива:

string s = "hello";

cout << s[0];  // h
s[0] = 'H';

Строку можно пройти обычным циклом:

for (size_t i = 0; i < s.size(); ++i) {
    cout << s[i];
}

Создание и склеивание строк

Строки можно присваивать друг другу, складывать и дописывать в конец.

string a = "Hello";
string b = "world";

string c = a + ", " + b;
a += '!';
a += "!!";

Конструктор string(n, c) создаёт строку из n одинаковых символов.

string s(5, '*');  // "*****"

Один символ можно добавить в конец методом push_back.

s.push_back('!');

Поиск: find

Метод find ищет первое вхождение символа или подстроки. Он возвращает индекс найденного фрагмента.

string s = "abracadabra";

size_t p1 = s.find('c');     // 4
size_t p2 = s.find("cad");   // 4

Вторым параметром можно указать позицию, с которой начинается поиск.

size_t p = s.find('a', 5);

Если ничего не найдено, возвращается специальное значение string::npos.

size_t p = s.find('@');

if (p == string::npos) {
    cout << "not found";
}
Результат поиска удобно сохранить в переменную и затем проверить его на string::npos. Для позиций строки обычно используют тип size_t.

Поиск одного из нескольких символов

find_first_of ищет первый символ, который входит в заданный набор.

string s = "computer";
size_t p = s.find_first_of("aeiou");  // позиция первой гласной

Как и у find, можно передать начальную позицию поиска:

size_t p = s.find_first_of("aeiou", 4);

Есть ещё три похожих метода:

Метод Что ищет
find_first_of первый символ из заданного набора
find_last_of последний символ из заданного набора
find_first_not_of первый символ, которого нет в заданном наборе
find_last_not_of последний символ, которого нет в заданном наборе

Поиск справа: rfind

rfind работает похоже на find, но ищет последнее вхождение.

string s = "one two one";
size_t p = s.rfind("one");

Получение подстроки: substr

Метод substr(pos, count) возвращает часть строки длиной count, начиная с позиции pos.

string s = "Hello, world!";

string a = s.substr(7, 5);  // "world"
string b = s.substr(7);     // "world!"

Если второй параметр не указан, берутся все символы до конца строки.

Удаление: erase

erase(pos, count) удаляет count символов, начиная с позиции pos.

string s = "abcXYZdef";

s.erase(3, 3);  // "abcdef"

Если количество не указано, удаляется хвост строки от pos до конца.

s.erase(3);

Вставка: insert

insert вставляет строку или символы перед указанной позицией.

string s = "Helloworld";

s.insert(5, ", ");  // "Hello, world"

Можно вставить несколько одинаковых символов:

s.insert(0, 3, '*');

Замена: replace

replace(pos, count, str) удаляет count символов с позиции pos и вставляет вместо них строку str.

string s = "red cat";

s.replace(0, 3, "black");  // "black cat"

Пустая строка и очистка

Метод empty() проверяет, нет ли в строке символов. Метод clear() удаляет всё содержимое строки.

if (s.empty()) {
    cout << "empty";
}

s.clear();

Символы: цифры и буквы

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

char c = s[i];

bool digit = ('0' <= c && c <= '9');
bool lower = ('a' <= c && c <= 'z');
bool upper = ('A' <= c && c <= 'Z');

Числовое значение десятичной цифры можно получить вычитанием символа '0'.

char c = '7';
int x = c - '0';  // 7

Краткая таблица

Запись Назначение
s.size() длина строки
s[i] символ с индексом i
s.find(x, pos) первое вхождение x, начиная с pos
s.rfind(x) последнее вхождение x
s.find_first_of(chars, pos) первый символ из набора chars
string::npos значение «не найдено»
s.substr(pos, count) получить подстроку
s.erase(pos, count) удалить часть строки
s.insert(pos, str) вставить строку
s.replace(pos, count, str) заменить часть строки
s.push_back(c) добавить символ в конец
s.empty() проверить, пуста ли строка
s.clear() очистить строку