2

私はboost::tokenizerCSVのようなファイルを読むために使用しています。トークンを に保存していstd::vectorます。うまく機能しますが、boost::iteratorトークンごとに のみを保存したいです。

私は試した:

#include <string>
#include <boost/tokenizer.hpp>
#include <boost/range/iterator_range.hpp>

typedef std::string::const_iterator string_iter;
typedef boost::iterator_range<string_iter> string_view;

int main(){
    std::string line;

    std::vector<string_view> contents;

    boost::tokenizer<boost::escaped_list_separator<char>, string_iter, string_view> tok(line.begin(), line.end());
    contents.assing(tok.begin(), tok.end());
}

しかし、コンパイルに失敗します:

/usr/include/boost/token_functions.hpp: 'bool boost::escaped_list_separator::operator()(InputIterator&, InputIterator, Token&) のインスタンス化 [with InputIterator = __gnu_cxx::__normal_iterator >; Token = boost::iterator_range<__gnu_cxx::__normal_iterator > >; 文字 = 文字; Traits = std::char_traits]': /usr/include/boost/token_iterator.hpp:70:11: 'void boost::token_iterator::initialize() から必要 [with TokenizerFunc = boost::escaped_list_separator; イテレータ = __gnu_cxx::__normal_iterator >; Type = boost::iterator_range<__gnu_cxx::__normal_iterator > >]' /usr/include/boost/token_iterator.hpp:77:63: 'boost::token_iterator::token_iterator(TokenizerFunc, Iterator, Iterator) から必要 [with TokenizerFunc =ブースト::escaped_list_separator; イテレータ = __gnu_cxx::__normal_iterator >; Type = boost::iterator_range<__gnu_cxx::__normal_iterator > >]' /usr/include/boost/tokenizer.hpp:86:53: 'boost::tokenizer::iter boost::tokenizer::begin() const から必要[with TokenizerFunc = boost::escaped_list_separator; イテレータ = __gnu_cxx::__normal_iterator >; Type = boost::iterator_range<__gnu_cxx::__normal_iterator > >; boost::tokenizer::iter = boost::token_iterator, __gnu_cxx::__normal_iterator >, boost::iterator_range<__gnu_cxx::__normal_iterator > > >]' /home/wichtounet/dev/gooda-to-afdo-converter/src/ gooda_reader.cpp:58:37: ここから必要 /usr/include/boost/token_functions.hpp:187:16: エラー: 'tok += (& next) の 'operator+=' に一致しません->__gnu_cxx::__normal_iterator <_Iterator, _Container>::operator* >()' /usr/include/boost/token_functions.hpp:193:11: エラー: 'tok += (& next)->__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* >()' /usr/include/boost/token_functions.hpp: の 'operator+=' に一致しません: インスタンス化中'void boost::escaped_list_separator::do_escape(iterator&, iterator, Token&) の [with iterator = __gnu_cxx::__normal_iterator >; Token = boost::iterator_range<__gnu_cxx::__normal_iterator > >; 文字 = 文字; Traits = std::char_traits]': /usr/include/boost/token_functions.hpp:176:11: required from 'bool boost::escaped_list_separator::operator()(InputIterator&, InputIterator, Token&) [with InputIterator = __gnu_cxx: :__normal_iterator >; Token = boost::iterator_range<__gnu_cxx::__normal_iterator > >; 文字 = 文字; Traits = std::char_traits]' /usr/include/boost/token_iterator.hpp:70:11: 'void boost::token_iterator::initialize() から必要 [with TokenizerFunc = boost::escaped_list_separator; イテレータ = __gnu_cxx::__normal_iterator >; Type = boost::iterator_range<__gnu_cxx::__normal_iterator > >]' /usr/include/boost/token_iterator.hpp:77:63: 'boost::token_iterator::token_iterator(TokenizerFunc, Iterator, Iterator) から必要 [with TokenizerFunc =ブースト::escaped_list_separator; イテレータ = __gnu_cxx::__normal_iterator >; Type = boost::iterator_range<__gnu_cxx::__normal_iterator > >]' /usr/include/boost/tokenizer.hpp:86:53: 'boost::tokenizer::iter boost::tokenizer::begin() const から必要[with TokenizerFunc = boost::escaped_list_separator; イテレータ = __gnu_cxx::__normal_iterator >; Type = boost::iterator_range<__gnu_cxx::__normal_iterator > >; ブースト::トークナイザー::

また、 を使用して 2 つの反復子を自分で計算しようとしましたboost::token_iteratorが、これまでのところ成功していません。

一部のパフォーマンスを節約するために、文字列ではなく各トークンのイテレータ範囲のみを取得するソリューションはありますか?

4

2 に答える 2

3

これはうまくいきません。は、トークナイザー関数のtokenizer結果に追加できる型 (3 番目のテンプレート引数) を想定しています。具体的には、 operator を提供する必要があります+= ( tokenizer<...>::iterator::value_type )。以下のコード スニペットを使用すると、さらに一歩進めることができますが、努力する価値があるかどうかはわかりません...

#include <string>
#include <boost/tokenizer.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>
#include <cstddef>

typedef std::string::const_iterator string_iter;
typedef boost::iterator_range<string_iter> string_view;

// a constant size character buffer, skips anything beyond CSize...
template< std::size_t CSize >
class assignable_view {
   std::size_t m_size;
   char m_buffer[CSize];

   friend std::ostream& operator << (std::ostream& p_out, assignable_view const & p_view)
   {
      if (p_view.m_size > 0u) {
         std::copy(p_view.m_buffer, p_view.m_buffer + p_view.m_size, std::ostream_iterator<char>(p_out));
      }
      return p_out;
   }

public:
   template <class TIter>
   void operator += (TIter p_input) 
   {
      if (m_size < CSize) {
         m_buffer[m_size++] = p_input;
      }   
   }   
   assignable_view() 
      : m_size(0u) {}
};

int main(){
    std::string line
        = "Field 1,\"putting quotes around fields, allows commas\",Field 3";

    std::vector<string_view> contents;

    boost::tokenizer<
       boost::escaped_list_separator<char>, 
       string_iter, 
       assignable_view<11>    
    > tok(line.begin(), line.end());

    for (auto const & t_s : tok) {
       std::cout << t_s << std::endl;
    }
    //contents.assing(tok.begin(), tok.end());
}
于 2012-11-10T10:13:30.763 に答える
3

ああ!インクルードが必要です:

#include <iostream>
#include <boost/tokenizer.hpp>
#include <boost/range/iterator_range.hpp>
#include <string>

int main()
{
    std::string line;
    typedef std::string::const_iterator string_iter;
    typedef boost::iterator_range<string_iter> string_view;

    boost::tokenizer<boost::escaped_list_separator<char>, string_iter, string_view> tok(line.begin(), line.end());
}

正常にコンパイルされます

于 2012-11-08T20:25:21.797 に答える