Use the find
, erase
, and length
member functions of
basic_string
:
std::string t = "Banana Republic"; std::string s = "nana"; std::string::size_type i = t.find(s); if (i != std::string::npos) t.erase(i, s.length());
This will erase s.length()
elements starting at the
index where find
found the first occurrence of the
substring.
There are lots of variations on the theme of finding a substring and removing it. For
example, you may want to remove all instances of a substring instead of just one. Or just
the last one. Or the seventh one. Each time the steps are the same: find the index of the
beginning of the pattern you want to remove, then call erase
on that index for the next n characters, where
n is the length of the pattern string. See Recipe 4.9 for the different member
functions for finding things in strings.
Chances are you also want to make your substring-removal function generic, so you can use it on strings of any kind of character. Example 4-19 offers a generic version that removes all instances of the pattern from a string.
Example 4-19. Remove all substrings from a string (generic version)
#include <string> #include <iostream> using namespace std; template<typename T> void removeSubstrs(basic_string<T>& s, const basic_string<T>& p) { basic_string<T>::size_type n = p.length(); for (basic_string<T>::size_type i = s.find(p); i != basic_string<T>::npos; i = s.find(p)) s.erase(i, n); } int main() { string s = "One fish, two fish, red fish, blue fish"; string p = "fish"; removeSubstrs(s, p); cout << s << '\n'; }
The basic_string
member function erase
is what does the important work here. In <string>
, it is overloaded three times. The version I
used in Example 4-19 accepts the index to
begin erasing at and the number of characters to erase. Another version accepts starting
and ending iterator arguments, and there is a version that takes a single iterator and
erases the element at that location. To ensure optimal performance, prefer the first two
when you plan to delete multiple contiguous elements instead of repeatedly calling
s.erase(iter)
for each element you want to erase. In
other words, use member functions that operate on ranges instead of single
elements—especially for those member functions that modify the contents of the string (or
sequence). By doing so, you will avoid the extra function calls to erase
for each element in the sequence, and you will permit
the string
implementation to more
intelligently manage its data.
Get C++ Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.