我正在使用boost::tokenizer读取类似CSV的文件。我将 token 存储在std::vector中。它运作良好,但是我只想为每个 token 存储一个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());
}

但是它无法编译:



我也只是尝试使用boost::token_iterator自己计算两个迭代器,但是到目前为止,我还没有成功。

是否有一种解决方案,只获取每个 token 的迭代器范围而不是字符串,以节省性能?

最佳答案

这行不通。 tokenizer需要一个类型(第三个模板参数),该类型可以附加在tokenizer函数的结果之后。具体来说,它必须提供运算符+= ( tokenizer<...>::iterator::value_type )。下面的code snippet应该使您更进一步,尽管我不确定是否值得付出努力……

#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());
}

10-07 17:20