Строковый итератор несовместим для чтения каждой строки

У меня есть std :: ostringstream.
Я хотел бы повторить для каждой строки этого std :: ostringstream.

Я использую Boost :: Tokenizer:

std::ostringstream HtmlStream;
.............
typedef boost::tokenizer<boost::char_separator<char> > line_tokenizer;
line_tokenizer tok(HtmlStream.str(), boost::char_separator<char>("\n\r"));

for (line_tokenizer::const_iterator i = tok.begin(), end = tok.end(); i != end; ++i)
{
std::string str = *i;
}

На линии

for (line_tokenizer::const_iterator i = tok.begin(), end = tok.end(); i != end;

У меня есть ошибка подтверждения с «несовместимым итератором строки».
Я читал об этой ошибке, в Google и на StackOverflow тоже, но у меня есть трудности, чтобы найти свою ошибку.

Кто-нибудь может мне помочь, пожалуйста?

Большое спасибо,

С наилучшими пожеланиями,

Nixeus

1

Решение

Мне нравится делать его не копирующим для эффективности / сообщения об ошибках:

Видеть это Жить на Колиру

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <iostream>
#include <vector>

int main()
{
auto const& s = "hello\r\nworld";

std::vector<boost::iterator_range<char const*>> lines;
boost::split(lines, s, boost::is_any_of("\r\n"), boost::token_compress_on);

for (auto const& range : lines)
{
std::cout << "at " << (range.begin() - s) << ": '" << range  << "'\n";
};
}

Печать:

at 0: 'hello'
at 7: 'world'

Это более эффективно, чем большинство показанных альтернатив. Конечно, если вам нужны дополнительные возможности анализа, рассмотрите Boost Spirit:

Видеть это Жить на Колиру

#include <boost/spirit/include/qi.hpp>

int main()
{
std::string const s = "hello\r\nworld";

std::vector<std::string> lines;

{
using namespace boost::spirit::qi;
auto f(std::begin(s)),
l(std::end(s));
bool ok = parse(f, l, *(char_-eol) % eol, lines);
}

for (auto const& range : lines)
{
std::cout << "'" << range  << "'\n";
};
}
2

Другие решения

Других решений пока нет …