if (n > s.length())
s.append(n - s.length(), c);
}
int main() {
string s = 'Appendix A';
wstring ws = L'Acknowledgments'; // 'L' указывает, что
// этот литерал состоит из
pad(s, 20. '*'); // широких символов
pad(ws, 20, L'*');
// cout << s << std::endl; // He следует пытаться выполнить это
wcout << ws << std::endl; // одновременно
}
pad
в примере 4.1 дополняет данную строку s
до длины n, используя символ c
. Так как шаблон функции использует параметризованный тип элементов строки (T
), он будет работать для basic_string
из любых символов: char
, wchar_t
или любых других, определенных пользователем.
4.2. Обрезка строк
Требуется обрезать несколько символов в конце или начале строки, обычно пробелов.
Для определения позиции строки, которую требуется удалить, используйте итераторы, а для ее удаления — метод erase
. Пример 4.2 показывает функцию rtrim
, которая удаляет символ в конце строки.
#include <string>
#include <iostream>
// Подход для строк из узких символов
void rtrim(std::string& s, char с) {
if (s.empty()) return;
std::string::iterator p;
for (p = s.end(); p != s.begin() && *--p == c;);
if (*p != c) p++;
s.erase(p, s.end());
}
int main() {
std::string s = 'zoo';
rtrim(s, 'o');
std::cout << s << '
';
}
Пример 4.2 выполняет все необходимое для строк длины char
, но работает basic_string
и шаблон функции. Пример 4.3 использует для удаления символов в конце строки любого типа шаблон функции.
#include <string>
#include <iostream>
using namespace std;
// Общий подход к обрезке отдельных
// символов строки
template<typename T>
void rtrim(basic_string<T>& s, T с) {
if (s.empty()) return;
typename basic_string<T>::iterator p;
for (p = s.end(); p != s.begin() && *--p == c;);
if (*p != c) p++;
s.erase(p, s.end());
}
int main() {
string s = 'Great!!!!';
wstring ws = L'Super!!!!';
rtrim(s, '!');
rtrim(ws, L'!');
cout << s << '
';
wcout << ws << L'
';
}
Эта функция работает точно так же, как и предыдущая, необобщенная версия из примера 4.2, но так как она параметризована по типу символов, она будет работать для basic_string
любого типа.
Примеры 4.2 и 4.3 удаляют из строки последовательность одного символа. Однако обрезка пробелов выглядит по-другому, так как пробельный символ может быть представлен одним из нескольких символов. Для удобства стандартная библиотека предоставляет простейший способ справиться с этим: функцию isspace
из заголовочного файла <cctype>
(и ее wchar_t
- эквивалент iswspace
из <cwctype>
). Пример 4.4 определяет общую функцию, которая обрезает концевые пробелы.
#include <string>
#include <iostream>
#include <cctype>
#include <cwctype>
using namespace std;
template<typename T, typename F>
void rtrimws(basic_string<T>& s, F f) {
if (s.empty()) return;
typename basic_string<T>::iterator p;
for (p = s.end(); p ! = s.begin() && f(*--p););
if (!f(*p))