Чтение онлайн

ЖАНРЫ

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
, которая удаляет символ в конце строки.

Пример 4.2. Обрезка символов строки

#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 << '\n';

}

Обсуждение

Пример 4.2 выполняет все необходимое для строк длины

char
, но работает только для них. Аналогично тому, что показано в примере 4.1, можно использовать общий дизайн
basic_string
и шаблон функции. Пример 4.3 использует для удаления символов в конце строки любого типа шаблон функции.

Пример 4.3. Обобщенная версия rtrim

#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 << '\n';

 wcout << ws << L'\n';

}

Эта

функция работает точно так же, как и предыдущая, необобщенная версия из примера 4.2, но так как она параметризована по типу символов, она будет работать для
basic_string
любого типа.

Примеры 4.2 и 4.3 удаляют из строки последовательность одного символа. Однако обрезка пробелов выглядит по-другому, так как пробельный символ может быть представлен одним из нескольких символов. Для удобства стандартная библиотека предоставляет простейший способ справиться с этим: функцию

isspace
из заголовочного файла
<cctype>
(и ее
wchar_t
– эквивалент
iswspace
из
<cwctype>
). Пример 4.4 определяет общую функцию, которая обрезает концевые пробелы.

Пример 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))

p++;

 s.erase(p, s.end);

}

// Перегрузка для облегчения вызовов в клиентском коде

void rtrimws(string& s) {

 rtrimws(s, isspace);

}

void rtrimws(wstring& ws) {

 rtrimws(ws, iswspace);

}

int main {

 string s = "zing ";

 wstring ws = L"zong ";

 rtrimws(s) rtrimws(ws);

 cout << s << "|\n";

 wcout << ws << L"|\n";

}

Шаблон функции

rtrimws
в примере 4 4 — это шаблон обобщённой функции, аналогичной предыдущим примерам, которая принимает
basic_string
и удаляет пробелы в ее конце. Но в отличие от других примеров, она для проверки элемента строки и определения того, должен ли он быть удален, принимает не символ, а объект функции.

Перегружать

rtrimws
, как это сделано в предыдущем примере, необязательно, но это упрощает синтаксис использования функции, так как вызывающий код при ее использовании может опустить аргумент логической функции.

Но, увы, это решение требует, чтобы вы писали код сами. Если же вы предпочитаете использовать библиотеку — и именно это и следует делать, — то библиотека Boost String Algorithms предоставляет огромное количество функций для обрезки строки, и в ней на верняка есть то, что вам надо. На самом деле, в библиотеке String Algorithms имеется огромное количество удобных функций обрезки, и при возможности использования Boost на них следует посмотреть. Таблица 4.1 приводит шаблоны функций этой библиотеки, используемые для обрезки строк, включая некоторые вспомогательные функции. Так как это шаблоны функций, они имеют параметры шаблонов, представляющие различные используемые типы. Вот что они означают.

Поделиться с друзьями: