Например, может потребоваться удалить все вхождения подстроки, а не одно из них. Или только последнее. Или седьмое. Каждый раз действия будут одни и те же: найдите индекс начала шаблона, который требуется удалить, затем вызовите erase
для этого индекса и
Также велика вероятность, что вам потребуется сделать функцию удаления обобщенной, так чтобы ее можно было использовать с любыми типами символов. Пример 4.19 предлагает общую версию, которая удаляет все вхождения шаблона в строке.
#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 << '
';
}
Здесь всю важную работу выполняет метод erase basic_string
. В <string>
он перегружен три раза. Использованная в примере 4.19 версия принимает индекс, с которого требуется начать удаление, и число удаляемых символов. Другая версия принимает в качестве аргументов начальный и конечный итераторы, а также есть версия, которая принимает единственный итератор и удаляет элемент, на который он указывает. Чтобы обеспечить оптимальную производительность при планировании удаления нескольких последовательных элементов, используйте первые две версии и не вызывайте s.erase(iter)
несколько раз для удаления каждого из идущих подряд элементов. Другими словами, используйте методы, работающие с диапазонами, а не с одним элементом, особенно в случае тех методов, которые изменяют содержимое строки (или последовательности). В этом случае вы избежите дополнительных вызовов функции erase
для каждого элемента последовательности и позволите реализации string
более грамотно управлять ее содержимым.
4.12. Преобразование строки к нижнему или верхнему регистру
Имеется строка, которую требуется преобразовать к нижнему или верхнему регистру.
Для преобразования символов к нижнему или верхнему регистру используйте функции toupper
и tolower
из заголовочного файла <cctype>
. Пример 4.20 показывает, как использовать эти функции. Смотри также обсуждение альтернативных методик.
#include <iostream>
#include <string>
#include <cctype>
#include <cwctype>
#include <stdexcept>
using namespace std;
void toUpper(basic_string<char>& s) {
for (basic_string<char>::iterator p = s.begin();
p != s.end(); ++p) {
*p = toupper(*p); // toupper is for char
}
}
void toUpper<basic_string<wchar_t>& s) {
for (basic_string<wchar_t>::iterator p = s.begin();
p != s.end(); ++p) {
*p = towupper(*p); // towupper is for wchar_t
}
}
void toLower(basic_string<char>& s) {
for (basic_string<char>::iterator p = s.begin();
p != s.end(); ++p) {
*p = tolower(*p);
}
}
void toLower(basic_string<wchar_t>& s) {
for (basic_string<wchar_t>::iterator p = s.begin();
p != s.end(); ++p) {
*p = towlower(*p);
}
int main() {
string s = 'shazam';
wstring ws = L'wham';
toUpper(s); toUpper(ws);
cout << 's = ' << s << endl;
wcout << 'ws = ' << ws << endl;
toLower(s);
toLower(ws);
cout << 's = ' << s << endl;
wcout << 'ws = ' << ws << endl;