Reading input from a text file and extracting it - C ++

I am trying to read a text file line by line and extract data into my program. In fact, a C ++ program will read an input file already made, which is in this format:

Republican Senator John McMahon Democrat Mayor Steven Markel Republican Judge Matt Stevens Democrat Senator Anthony Quizitano SR MD JR ... .. .. 

The format mainly consists of the first three lines: Party, Position and Name, and the following lines indicate the β€œresults”, which are presented in the form:

[first letter of position] [party voted in favor]

So, for example, if you see SR, it means that 1 vote for the senator, and he goes to the Republican candidate.

Here is what I still have:

  #include<fstream> int main() { std::ifstream input("file.txt"); } 

I understand that this will allow me to enter the file and go through it line by line, but I'm not sure how I should proceed to achieve this from here ... any help?

Thanks!

+4
source share
1 answer

Here, for pleasure and glory, an implementation based on Boost Spirit. I added more fake votes, so there might be something to display.

  • I was not sure if the ratio between the candidates and the votes was 1: 1 (I am not a US citizen, and I do not know whether the listed candidates will vote or vote for), so I decided to use only fake data.

     const std::string input = "Republican Senator John McMahon\n" "Democrat Senator Anthony Quizitano\n" "SR\n" "SR\n" "SR\n" "Democrat Mayor Steven Markel\n" "Republican Judge Matt Stevens\n" "MD\n" "JR\n" "SR\n" "SR\n"; 

    However, the code can be used for both purposes.

  • I did it no matter in what order the input appears.
  • If you wish, you can claim that the single letters (S, M, J) actually correspond to the positions listed before this point. Enable this by uncommenting the check with posletter_check

Watch the live demo http://liveworkspace.org/code/d9e39c19674fbf7b2419ff88a642dc38

 #define BOOST_SPIRIT_USE_PHOENIX_V3 #define BOOST_RESULT_OF_USE_DECLTYPE #include <boost/fusion/adapted.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> #include <iomanip> namespace qi = boost::spirit::qi; namespace phx = boost::phoenix; struct Candidate { std::string party, position, name; }; BOOST_FUSION_ADAPT_STRUCT(Candidate, (std::string, party)(std::string, position)(std::string, name)) typedef std::map<std::pair<char, char>, size_t> Votes; typedef std::vector<Candidate> Candidates; template <typename It> struct parser : qi::grammar<It> { mutable Votes _votes; mutable Candidates _candidates; parser() : parser::base_type(start) { using namespace qi; using phx::bind; using phx::ref; using phx::val; start = (line % eol) >> *eol >> eoi; line = vote [ phx::bind(&parser::register_vote, phx::ref(*this), _1) ] | candidate [ phx::push_back(phx::ref(_candidates), _1) ] ; vote %= graph // Comment the following line to accept any single // letter, even if a matching position wasn't seen // before: [ _pass = phx::bind(&parser::posletter_check, phx::ref(*this), _1) ] >> ' ' >> char_("RD") ; candidate = (string("Republican") | string("Democrat")) >> ' ' >> as_string [ +graph ] >> ' ' >> as_string [ +(char_ - eol) ] ; } private: bool posletter_check(char posletter) const { for (auto& c : _candidates) if (posletter == c.position[0]) return true; return false; } void register_vote(Votes::key_type const& key) const { auto it = _votes.find(key); if (_votes.end()==it) _votes[key] = 1; else it->second++; } qi::rule<It, Votes::key_type()> vote; qi::rule<It, Candidate()> candidate; qi::rule<It> start, line; }; int main() { const std::string input = "Republican Senator John McMahon\n" "Democrat Senator Anthony Quizitano\n" "SR\n" "SR\n" "SR\n" "Democrat Mayor Steven Markel\n" "Republican Judge Matt Stevens\n" "MD\n" "JR\n" "SR\n" "SR\n"; std::string::const_iterator f(std::begin(input)), l(std::end(input)); parser<std::string::const_iterator> p; try { bool ok = qi::parse(f,l,p); if (ok) { std::cout << "\ncandidate list\n"; std::cout << "------------------------------------------------\n"; for (auto& c : p._candidates) std::cout << std::setw(20) << c.name << " (" << c.position << " for the " << c.party << "s)\n"; std::cout << "\nVote distribution:\n"; std::cout << "------------------------------------------------\n"; for (auto& v : p._votes) std::cout << '(' << v.first.first << "," << v.first.second << "): " << v.second << " votes " << std::string(v.second, '*') << "\n"; } else std::cerr << "parse failed: '" << std::string(f,l) << "'\n"; if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n"; } catch(const qi::expectation_failure<std::string::const_iterator>& e) { std::string frag(e.first, e.last); std::cerr << e.what() << "'" << frag << "'\n"; } } 

Output:

 candidate list ------------------------------------------------ John McMahon (Senator for the Republicans) Anthony Quizitano (Senator for the Democrats) Steven Markel (Mayor for the Democrats) Matt Stevens (Judge for the Republicans) Vote distribution: ------------------------------------------------ (J,R): 1 votes * (M,D): 1 votes * (S,R): 5 votes ***** 
+2
source

Source: https://habr.com/ru/post/1438713/


All Articles