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 из заголовочного файла (и ее wchar_t-эквивалент iswspace из ). Пример 4.4 определяет общую функцию, которая обрезает концевые пробелы.

Пример 4.4. Удаление концевых пробелов

#include

#include

#include

#include

using namespace std;

template

void rtrimws(basic_string& s, F f) {

 if (s.empty()) return;

 typename basic_string::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 приводит шаблоны функций этой библиотеки, используемые для обрезки строк, включая некоторые вспомогательные функции. Так как это шаблоны функций, они имеют параметры шаблонов, представляющие различные используемые типы. Вот что они означают.

Seq

Это тип, удовлетворяющий требованиям к последовательностям стандарта C++.

Coll

Это тип, удовлетворяющий менее строгим требованиям, чем стандартная последовательность. Для того чтобы узнать, каким требованиям удовлетворяет коллекция, обратитесь к определениям Boost String Algorithms.

Pred

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

OutIt

Это тип, который удовлетворяет требованиям выходного итератора, как определено в стандарте С++. В частности, он должен поддерживать инкрементирование и присвоение нового положения для добавления элементов в конец последовательности, на которую он указывает.

Табл. 4.1. Шаблоны функций обрезки строк Boost

Перейти на страницу:

Похожие книги