1 апр. 2009 г.

Использование boost::tokenizer

Нередко в практике программистов встречаются задачи, когда нужно разобрать строку (как еще иногда говорят - распарсить). Решений этой задачи - множество. Это и простейший поиск очередного символа-разделителя, и регулярные выражения, и специальные алгоритмы (например, из коллекции boost::string_algo). Но иногда логика разбиения строки на части (т. е. логика разбора) может быть ну совсем уж специфичная. Или регулярное выражение получается очень уж навороченное. Или по каким-то причинам библиотека регулярных выражений (тот же boost::regex) неприменима. Тогда на помощь может придти boost::tokenizer.

Вот пример его использования:

#include <iostream>
#include <string>
#include <list>

#include <boost/tokenizer.hpp>
#include <boost/iostreams/device/file.hpp> // file_source
#include <boost/iostreams/stream.hpp>      // stream

int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
        // определяем длиннючие типы
        typedef boost::iostreams::file_source file_device_type;
        typedef boost::iostreams::stream<file_device_type> stream_type;
        typedef boost::char_separator<char> token_func_type;
        typedef boost::tokenizer<token_func_type> tokenizer_type;
        typedef std::list<std::string> token_list_type;
        
        // открываем файл
        stream_type strm ( file_device_type("C:\\temp.txt", BOOST_IOS::out|BOOST_IOS::binary) );
        strm >> std::noskipws;
        
        // читаем его содержимое в буфер
        std::string buffer;
        std::copy (
            std::istream_iterator<char>(strm),
            std::istream_iterator<char>(),
            std::back_inserter<std::string>(buffer) );
    
        // разбиваем буфер на токены-слова
        // и помещаем их в список строк
        //boost::tokenizer<> tok(buffer);
        token_func_type sep(" \t\n");
        tokenizer_type tok(buffer, sep);
        token_list_type tokens_list;
        std::copy (
            tok.begin(),
            tok.end(),
            std::back_inserter<token_list_type>(tokens_list) );

        // выводим список на печать
        std::copy (
            tokens_list.begin(),
            tokens_list.end(),
            std::ostream_iterator<std::string>(std::cout, "\n") );
    }
    catch ( std::exception & exc )
    {
        std::cerr << "Exception: " << exc.what() << std::endl;
    }
    return 0;
}

Комментариев нет:

Отправить комментарий