string::size_type adv = (repeats) ? 1 : p.length();
int j;
for (j = 1; j < n && i != basic_string
i = s.find(p, i+adv);
if (j == n)
return(i);
else
return(-1);
}
int main() {
string s = AGATGCCATATATATACGATATCCTTA";
string p = "ATAT";
cout << p << " без повторений встречается в позиции "
<< nthSubstrg(3, s, p) << '\n';
cout << p << " с повторениями встречается в позиции "
<< nthSubstrg(3, s, p, true) << '\n';
}
Вывод для строк, использованных в примере 4.18, выглядит так.
ATAT без повторений встречается в позиции 18
ATAT с повторениями встречается в позиции 11
Рецепт 4.9.
4.11. Удаление подстроки из строки
Требуется удалить из строки подстроку.
Используйте методы basic_string find, erase и length:
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());
Этот код удаляет s.length() элементов, начиная с индекса, по которому find находит первое вхождение подстроки.
На практике встречается огромное количество вариаций на тему поиска и удаления подстрок. Например, может потребоваться удалить все вхождения подстроки, а не одно из них. Или только последнее. Или седьмое. Каждый раз действия будут одни и те же: найдите индекс начала шаблона, который требуется удалить, затем вызовите erase для этого индекса и
Также велика вероятность, что вам потребуется сделать функцию удаления обобщенной, так чтобы ее можно было использовать с любыми типами символов. Пример 4.19 предлагает общую версию, которая удаляет все вхождения шаблона в строке.
#include
#include
using namespace std;
template
void removeSubstrs(basic_string
const basic_string
basic_string
for (basic_string
i != basic_string
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';
}
Здесь всю важную работу выполняет метод erase basic_string. В он перегружен три раза. Использованная в примере 4.19 версия принимает индекс, с которого требуется начать удаление, и число удаляемых символов. Другая версия принимает в качестве аргументов начальный и конечный итераторы, а также есть версия, которая принимает единственный итератор и удаляет элемент, на который он указывает. Чтобы обеспечить оптимальную производительность при планировании удаления нескольких последовательных элементов, используйте первые две версии и не вызывайте s.erase(iter) несколько раз для удаления каждого из идущих подряд элементов. Другими словами, используйте методы, работающие с диапазонами, а не с одним элементом, особенно в случае тех методов, которые изменяют содержимое строки (или последовательности). В этом случае вы избежите дополнительных вызовов функции erase для каждого элемента последовательности и позволите реализации string более грамотно управлять ее содержимым.
4.12. Преобразование строки к нижнему или верхнему регистру
Имеется строка, которую требуется преобразовать к нижнему или верхнему регистру.
Для преобразования символов к нижнему или верхнему регистру используйте функции toupper и tolower из заголовочного файла . Пример 4.20 показывает, как использовать эти функции. Смотри также обсуждение альтернативных методик.
#include
#include
#include
#include
#include
using namespace std;
void toUpper(basic_string