C++. Сборник рецептов - [64]

Шрифт
Интервал

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

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

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

>#include

>#include

>#include

>#include


>using namespace std;

>using namespace boost;


>int main() {

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

> list results;

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

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

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

>  cout << *p << endl;

> }

>}

>split — это шаблон функции, принимающий три аргумента. Он объявлен вот так.

>template

>Seq& split(Seq& s, Coll& c, Pred p,

> token_compress_mode_type e = token_compress_off);

>Seq, >Coll и >Pred представляют типы результирующей последовательности, входной коллекции и предиката, используемого для определения, является ли очередной объект разделителем. Аргумент последовательности — это последовательность, определенная по стандарту C++, содержащая нечто, что может хранить части того, что находится во входной коллекции. Так, например, в примере 4.11 был использован >list, но вместо него можно было бы использовать и >vector. Аргумент коллекции — это тип входной последовательности. Коллекция — это нестандартная концепция, которая похожа на последовательность, но с несколько меньшими требованиями (за подробностями обратитесь к документации по Boost по адресу www.boost.org). Аргумент предиката — это объект унарной функции или указатель на функцию, которая возвращает >bool, указывающий, является ли ее аргумент разделителем или нет. Она вызывается для каждого элемента последовательности в виде >f(*it), где >it — это итератор, указывающий на элемент последовательности.

>is_any_of — это удобный шаблон функции, поставляющийся в составе String Algorithms, которая облегчает жизнь при использовании нескольких разделителей. Он конструирует объект унарной функции, которая возвращает >true, если переданный ей аргумент является членом набора. Другими словами:

>bool b = is_any_of("abc")('a'); // b = true

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

4.7. Разбиение строки на лексемы

Проблема

Требуется разбить строку на части, используя набор разделителей.

Решение

Для перебора элементов строки и поиска места нахождения следующих лексем и не-лексем используйте методы >find_first_of и >first_first_not_of. Пример 4.12 представляет простой класс >StringTokenizer, выполняющий эту задачу.

Пример 4.12. Разбиение строки на лексемы

>#include

>#include


>using namespace std;


>// Класс, разбивающий строку на лексемы.

>class StringTokenizer {

>public:

> StringTokenizer(const string& s, const char* delim = NULL) :

>  str_(s), count(-1), begin_(0), end_(0) {

>  if (!delim)

>   delim_ = " \f\n\r\t\v"; //по умолчанию пробельные символы

>  else

>   delim_ = delim;

>  // Указывает на первую лексему

>  begin_ = str_.find_first_not_of(delim);

>  end_ = str.find_first_of(delim_, begin_);

> }


> size_t countTokens() {

>  if (count_ >= 0) // если уже посчитали, то выход

>   return(count_);

>  string::size_type n = 0;

>  string::size_type i = 0;

>  for (;;) {

>   // переход на первую лексему

>   if ((i = str_.find_first_not_of(delim_, i)) == string::npos)

>    break;

>   // переход на следующий разделитель

>   i = str_.find_first_of(delim_, i+1);

>   n++;

>   if (i == string::npos) break;

>  }

>  return (count_ = n);

> }


> bool hasMoreTokens() { return(begin_ != end_); }


> void nextToken(string& s) {

>  if (begin_ != string::npos && end_ != string::npos) {

>   s = str_.substr(begin_, end_-begin_);

>   begin_ = str_.find_first_not_of(delim_, end_);

>   end_ = str_.find_first_of(delim_, begin_);

>  } else if (begin_ != string::npos && end_ == string::npos) {

>   s = str_.substr(begin_, str_.length()-begin_);

>   begin_ = str_.find_first_not_of(delim_, end_);

>  }

> }


>private:

> StringTokenizer() {}

> string delim_;

> string str_;

> int count_;

> int begin_;

> int end_;

>};


>int main() {

> string s = " razzle dazzle giddyup ";

> string tmp;

> StringTokenizer st(s);

> cout << "Здесь содержится" << st.countTokens() << " лексемы.\n";

> while (st.hasMoreTokens()) {

>  st.nextToken(tmp);

>  cout << "token = " << trap << '\n';


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.