As always, with delightfully underspecified questions like this, there's not a lot more than just showing "a way" to do "a thing". In this case, I used Boost Spirit (because you mentioned it):
Parsing into flat containers
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>
#include <map>
std::string const input(
">Header - name1\n"
"ID1 1 1 12\n"
"ID2 3 6 234\n"
">Header - name2\n"
"ID3 3 3 14\n"
"ID4 5 8 345\n"
);
using Header = std::string;
using Container = std::vector<int>;
using Data = std::map<Header, Container>;
int main()
{
namespace qi = boost::spirit::qi;
auto f(input.begin()), l(input.end());
Data data;
bool ok = qi::phrase_parse(f, l,
*(
'>' >> qi::raw[*(qi::char_ - qi::eol)] >> qi::eol
>> *(!qi::char_('>') >> qi::omit[qi::lexeme[+qi::graph]] >> *qi::int_ >> qi::eol)
), qi::blank, data);
if (ok)
{
std::cout << "Parse success\n";
for (auto const& entry : data)
{
std::cout << "Integers read with header '" << entry.first << "':\n";
for (auto i : entry.second)
std::cout << i << " ";
std::cout << "\n";
}
}
else
{
std::cout << "Parse failed\n";
}
if (f != l)
std::cout << "Remaining input: '" << std::string(f, l) << "'\n";
}
Prints
Parse success
Integers read with header 'Header - name1':
1 1 12 3 6 234
Integers read with header 'Header - name2':
3 3 14 5 8 345
Parsing into nested containers
Of course, if you wanted separate vectors for each line (don't expect efficiency) then you can simply replace the typedef:
using Container = std::list<std::vector<int> >; // or any other nested container
// to make printing work without further change:
std::ostream& operator<<(std::ostream& os, std::vector<int> const& v)
{
os << "[";
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(os, " "));
return os << "]";
}
Prints
Parse success
Integers read with header 'Header - name1':
[1 1 12 ] [3 6 234 ]
Integers read with header 'Header - name2':
[3 3 14 ] [5 8 345 ]