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

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

std::string rs;

rs.assign(s.rbegin, s.rend);

rbegin
и
rend
возвращают реверсивные итераторы. Реверсивные итераторы ведут себя так, как будто они просматривают последовательность в обратном порядке.
rbegin
возвращает итератор, который указывает на последний элемент, a
rend
возвращает итератор, указывающий на позицию перед первым элементом. Это в точности обратно тому, что делают
begin
и
end
.

Но должны

ли вы обращать строку? С помощью
rbegin
и
rend
для обратной строки можно использовать все методы или алгоритмы, работающие с диапазонами итераторов. А если требуется выполнить поиск в строке, то можно использовать
rfind
, которая делает то же, что и
find
, но начинает с конца строки и движется к ее началу. Для больших строк или большого количества строк обращение может оказаться очень дорогостоящим, так что при возможности избегайте его.

4.6. Разделение строки

Проблема

Требуется разделить строку с разделителями на несколько строк. Например, может потребоваться разделить строку

"Name|Address|Phone"
на три отдельных строки —
"Name"
,
"Address"
и
"Phone"
, удалив при этом разделитель.

Решение

Для перехода от одного вхождения разделителя к следующему используйте метод

find
класса
basic_string
, а для копирования каждой подстроки используйте
substr
. Для хранения результатов используйте любую стандартную последовательность. Пример 4.10 использует
vector
.

Пример 4.10. Разделение строки с разделителями

#include <string>

#include <vector>

#include <functional>

#include <iostream>

using namespace std;

void split(const string& s, char c, vector<string>& v) {

 string::size_type i = 0;

 string::size_type j = s.find(c);

 while (j != string::npos) {

v.push_back(s.substr(i, j-i));

i = ++j;

j = s.find(c, j);

if (j == string::npos)

v.push_back(s.substr(i, s.length));

 }

}

int main {

 vector<string> v;

 string s = "Account Name|Address 1|Address 2 |City";

 split(s, '|', v);

 for (int i = 0; i < v.size; ++i) {

cout << v[i] << '\n';

 }

}

Обсуждение

Превращение приведенного выше примера в шаблон функции, принимающий любой тип символов, тривиально — просто параметризуйте тип символов и

замените случаи использования
string
на
basic_string<T>
.

template<typename T>

void split(const basic_string<T>& s, T c,

 vector<basic_string<T> >& v) {

 basic_string<T>::size_type i = 0;

 basic_string<T>::size_type j = s.find(c);

 while (j != basic_string<T>::npos) {

v.push_back(s.substr(i, j-i));

i = ++j;

j = s.find(c, j);

if (j == basic_string<T>::npos)

v.push back(s.substr(i, s.length));

 }

}

Логика при этом не меняется.

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

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

string
пример использует метод
find
, а для копирования символов диапазона в новую
string
, помещаемую в
vector
, — метод
substr
. Это тот же самый принцип, который используется в функциях разбиения строк большинства скриптовых языков и является специальным случаем разделения строки текста на лексемы (tokenizing), описываемого в рецепте 4.7.

Разделение строки, использующей единственный символ-разделитель, является очень распространенной задачей, и неудивительно, что ее решение есть в библиотеке Boost String Algorithms. Оно просто в использовании. Чтобы увидеть, как разделить строку с помощью функции

split
из Boost, посмотрите на пример 4.11.

Пример 4.11. Разделение строки с помощью Boost

#include <iostream>

#include <string>

#include <list>

#include <boost/algorithm/string.hpp>

using namespace std;

using namespace boost;

int main {

 string s = "one,two,three,four";

 list<string> results;

 split(results, s, is_any_of(",")); // Обратите внимание - это boost::split

 for (list<string>::const_iterator p = results.begin;

p != results.end; ++p) {

Поделиться:
Популярные книги

Жалкая

Макинтайер Эмили
3. Долго и Несчастливо
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Жалкая

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Академия проклятий. Книги 1 - 7

Звездная Елена
Академия Проклятий
Фантастика:
фэнтези
8.98
рейтинг книги
Академия проклятий. Книги 1 - 7

Измена. Верни мне мою жизнь

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Верни мне мою жизнь

Измена

Рей Полина
Любовные романы:
современные любовные романы
5.38
рейтинг книги
Измена

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сердце для стража

Каменистый Артем
5. Девятый
Фантастика:
фэнтези
боевая фантастика
9.20
рейтинг книги
Сердце для стража

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Жена фаворита королевы. Посмешище двора

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Жена фаворита королевы. Посмешище двора

Как я строил магическую империю 5

Зубов Константин
5. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 5

Блуждающие огни 2

Панченко Андрей Алексеевич
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Блуждающие огни 2

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Маленькая слабость Дракона Андреевича

Рам Янка
1. Танцы на углях
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
Маленькая слабость Дракона Андреевича