Если надо добавить в конец строки другую строку, применяется метод append(), в который передается добавляемая строка:
#include <iostream> #include <string> int main() { std::string message{ "hello"}; message.append(" "); // добавляем пробел message.append("world"); // можно добавить по цепочке // message.append(" ").append("world"); std::cout << message << std::endl; // hello world }
Для вставки одной строки в другую применяется функция insert(). Она имеет несколько различных версий. Самая простая версия принимет индекс вставки и вставляемую строку:
#include <iostream> #include <string> int main() { std::string text {"insert into a text"}; std::string str {"a string "}; text.insert(7, str); std::cout << text << std::endl; // insert a string into a text }
В данном случае в строку text начиная с 7-го индекса вставляем строку str. В итоге переменная text будет равна "insert a string into a text".
Также можно вставлять строковый литерал:
std::string text {"Hello C++"}; text.insert(6, "C/"); // Hello C/C++
Можно вставлять часть подстроки:
std::string text {"Langs: C++"}; std::string langs {"Java, C, C#"}; text.insert(6, langs, 5, 3); // Langs: C, C++
Здесь в text вставляем из переменной langs 3 символа с 5-го индекса, то есть подстроку " C,".
Среди других версий функции insert()
также следует отметить версию, которая позволяет вставить определенный символ определенное число раз:
std::string text {"Number: 5678"}; text.insert(8, 5, '*'); // Number: *****5678
В данном случае вставляем в строку text символ * 5 раз начиная с 8 индекса.
Для замены в строке некоторой части применяется функция replace(). Эта функция также имеет много версий, поэтому рассмотрим самые распространенные.
Самая простая версия принимает три параметра:
std::string &std::string::replace(size_t _Off, size_t _Nx, const char *_Ptr)
Первый параметр - представляет индекс, с которого надо заменять подстроку. Второй параметр - количество заменяемых символов. Третий параметр - на какую строку надо заменить. Пример:
#include <iostream> #include <string> int main() { std::string text {"Lang: Java"}; text.replace(6, 4, "C++"); // Lang: C++ std::cout << text << std::endl; // Lang: C++ }
Здесь в строке text заменяем 4 символа с 6-го индекса на строку "C++". Таким образом, из строки "Lang: Java" мы получим строку "Lang: C++".
В предыдущем примере символы заменялись на строковый литерал. Но также можно заменять на объект string:
std::string text {"Lang: Java"}; std::string lang {"C++"}; text.replace(6, 4, lang); // Lang: C++
Нередко стоит задача заменить какой-то определенную подстроку, индекс которой может быть не известен. В этом случае мы можем воспользоваться поиском в строке, чтобы найти индекс подстроки и ее размер. Например, возьмем текст "Hello, Tom!" и заменим подстроку "Tom" на "Bob":
#include <iostream> #include <string> int main() { std::string text {"Hello, Tom!"}; const std::string separators {" ,;:.\"!\n"}; // разделители слова size_t start {text.find("Tom")}; // находим позицию подстроки size_t end {text.find_first_of(separators, start + 1)}; // Находим конец подстроки if(end == std::string::npos) // если разделители слова не найдены { end = text.length(); } text.replace(start, end - start, "Alice"); // заменяем подстроку std::cout << text << std::endl; // Hello, Alice! }
Здесь находим позицию первого символа подстроки "Tom" в тексте и сохраняем ее в переменную start. Символ, следующий за последним символом подстроки
"Tom", находится путем поиска символа разделителя из строки separators с помощью функции find_first_of()
. Далее используем найденные позиции индекса
в replace()
.
Однако в тексте может быть множество вхождений определенной подстроки (в нашем случае строки "Tom"), и может встать задача заменить все эти вхождения. Для этого мы можем использовать циклы:
#include <iostream> #include <string> int main() { std::string text {"Message to Tom: Hello, Tom!"}; std::string old_str{"Tom"}; // какую подстроку заменить std::string new_str{"Alice"}; // на какую строку заменить size_t start {text.find(old_str)}; // находим позицию подстроки while (start != std::string::npos) // находим и заменяем все вхождения строки old_str { text.replace(start, old_str.length(), new_str); // Замена old_str на new_str start = text.find(old_str, start + new_str.length()); } std::cout << text << std::endl; // Message to Alice: Hello, Alice! }
Здесь сначала находим индекс первого вхождения подстроки, которую надо заменить, и сохраняем этот индекс в переменную start. В цикле
заменяем последовательно все вхождения подстроки. После каждой замены находим индекс следующего вхождения, сохраняем его в переменную start и
повторяем цикл. Когда больше нет вхождений подстроки в текст, start будет содержать значение std::string::npos
, что завершает цикл.
Из других версий функции replace()
можно выделить функцию, которая заменяет подстроку определенным символом, который повторяется определенное количество раз:
std::string text {"Phone: +12345678901"}; text.replace(9, 6, 5, '*'); // Phone: +1*****8901
Здесь заменяет в строке text 6 символов начиная с 9-го индекса на 5 символов *.
Если надо не просто заменить символы, а удалить их из текста, также можно использовать функцию replace()
- в этом случае удаляемые символы фактически заменяются на пустую строку:
#include <iostream> #include <string> int main() { std::string text {"Hello Tom!"}; const std::string empty; text.replace(5, 4, empty); // Замена "Tom" на пустую строку std::cout << text << std::endl; // Hello! }
Однако С++ также предоставляет для удаления символов специальную функцию - erase(). В качестве параметров она принимает начальный индекс удаления и количество удаляемых символов:
#include <iostream> #include <string> int main() { std::string text {"Hello Tom!"}; text.erase(5, 4); // удаляем 4 символа с 5-го индекса std::cout << text << std::endl; // Hello! }
Аналогично можно удалить все вхождения определенной подстроки:
#include <iostream> #include <string> int main() { std::string text {"Hello Tom! Good bye Tom..."}; std::string to_delete{" Tom"}; // какую подстроку удалить size_t start {text.find(to_delete)}; // находим позицию подстроки while (start != std::string::npos) // находим и удаляем все вхождения to_delete { text.erase(start, to_delete.length()); start = text.find(to_delete, start + to_delete.length()); } std::cout << text << std::endl; // Hello! Good bye... }
Функция erase()
имеет ряд дополнительных версий. Так, можно оставить определенное количество символов с начала строки, а остальные удалить:
std::string text {"Hello Tom"}; text.erase(5); // удаляем все кроме первых 5 символов - остается "Hello"
Если в функцию не передается никаких параметров, то она удаляет все символы, и в результате получаем пустую строку:
std::string text {"Hello Tom"}; text.erase(); // пустая строка
Стоит отметить, что в стандарт С++20 была добавлена функция std::erase(), которая удаляет все вхождения определенного символа в строке:
#include <iostream> #include <string> int main() { std::string text {"Hello Tom! Good bye Tom..."}; std::erase(text, 'T'); // Удаляем символ T std::cout << text << std::endl; // Hello om! Good bye om... }
В данном случае удаляем из строки text символ T.