我正在使用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());
}