Let me show you the Boost Spirit approach to parsing input data like this.
If you start with a struct like
struct Staff
{
std::string title;
std::string firstName;
std::string familyName;
std::string position;
std::string room;
std::string email;
};
You can use a Spirit grammar like:
column = lexeme [ *~char_("\t\r\n") ];
start = column >> '\t' >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column;
And parse all rows into a vector like:
It f(std::cin), l;
std::vector<Staff> staff_members;
bool ok = qi::parse(f, l, grammar % qi::eol, staff_members);
if (ok)
{
for(auto const& member : staff_members)
{
std::cout << boost::fusion::as_vector(member) << "\n";
}
} else
{
std::cout << "Parsing failed\n";
}
if (f != l)
std::cout << "Remaining input '" << std::string(f, l) << "'\n";
Here's the complete test program Live on Coliru, sample run:
clang++ -std=c++11 -Os -Wall -pedantic main.cpp && ./a.out <<INPUT
Dr Sherine ANTOUN Lecturer 4327 3.204 sherine_antoun@gmail.com
Mr Jason SCRYPT Enthusiast 3472 9.204 jason_scrypt@yahoo.com
INPUT
Output:
(Dr Sherine ANTOUN Lecturer 4327 3.204 sherine_antoun@gmail.com)
(Mr Jason SCRYPT Enthusiast 3472 9.204 jason_scrypt@yahoo.com)
Remaining input '
'
Full Listing
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/tuple/tuple_io.hpp>
namespace qi = boost::spirit::qi;
struct Staff
{
std::string title;
std::string firstName;
std::string familyName;
std::string position;
std::string room;
std::string email;
};
BOOST_FUSION_ADAPT_STRUCT(Staff,
(std::string, title)
(std::string, firstName)
(std::string, familyName)
(std::string, position)
(std::string, room)
(std::string, email))
template <typename It, typename Skipper = qi::unused_type>
struct grammar : qi::grammar<It, Staff(), Skipper>
{
grammar() : grammar::base_type(start)
{
using namespace qi;
column = lexeme [ *~char_("\t\r\n") ];
start = column >> '\t' >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column;
}
private:
qi::rule<It, std::string(), Skipper> column;
qi::rule<It, Staff(), Skipper> start;
};
int main()
{
std::cin.unsetf(std::ios::skipws);
typedef boost::spirit::istream_iterator It;
grammar<It> grammar;
It f(std::cin), l;
std::vector<Staff> staff_members;
bool ok = qi::parse(f, l, grammar % qi::eol, staff_members);
if (ok)
{
for(auto const& member : staff_members)
{
std::cout << boost::fusion::as_vector(member) << "\n";
}
} else
{
std::cout << "Parsing failed\n";
}
if (f != l)
std::cout << "Remaining input '" << std::string(f, l) << "'\n";
}