2012-10-09 218 views
4

我正在嘗試逐行讀取文本文件並將數據提取到我的程序中。從本質上講,C++程序的必讀書已經取得的輸入文件的格式如下:從文本文件中讀取輸入並將其解壓 - C++

 Republican Senator John McMahon 
    Democrat Mayor Steven Markel 
    Republican Judge Matt Stevens 
    Democrat Senator Anthony Quizitano 
    S R 
    M D 
    J R 
    ... 
    .. 
    .. 

格式基本上是第一個3線包括黨,位置和名稱,並在次年線表示「結果「這是在形式:

[位置第一個字母] [方投票]

因此,舉例來說,如果你看到SR,這意味着1個投票支持參議員,並轉到共和黨候選人。

這是我到目前爲止有:

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

這是我的理解,這將讓我輸入的文件,一行一行地通過它,但我不知道我應該如何着手從這裏實現這個......任何幫助?

謝謝!

+0

簡單的方法? '輸入>> var1 >> var2 ... etc'循環播放,如果你的數據格式良好,你不必擔心檢查太多。我也會編輯標題。它說C,但問題顯然是C++ –

+0

位置總是保證每個聚會都有唯一的第一個字母,並且始終是一個單詞?名稱總是保證是兩個字嗎?爲什麼有,例如,當您可以從職位信中確定派對時,「S R」? R是多餘的。總會有3個候選人嗎? –

+0

他們保證採用這種格式,而且會有更多的候選人。這不是家庭作業,這是我正在爲自己工作的一個項目。 – user1732514

回答

2

這裏是爲了樂趣和榮耀,基於Boost Spirit的實現。我添加了更多的虛假投票輸入,所以可能會顯示某些內容。

  • 我不知道是否有一個1:候選人和投票之間的關係1(我不是美國公民,我不知道是否列出的候選人將進行投票或正在投票)。所以我決定只使用假數據。

    const std::string input = 
        "Republican Senator John McMahon\n" 
        "Democrat Senator Anthony Quizitano\n" 
        "S R\n" 
        "S R\n" 
        "S R\n" 
        "Democrat Mayor Steven Markel\n" 
        "Republican Judge Matt Stevens\n" 
        "M D\n" 
        "J R\n" 
        "S R\n" 
        "S R\n"; 
    

    然而,代碼可用於兩個目的。

  • 我把它作爲輸入顯示的順序是不重要的。
  • 可選地,您可以斷言單個字母(S,M,J)實際上對應於該點之前列出的位置。通過取消註釋與posletter_check

檢查啓用此觀看演示住在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" 
     "S R\n" 
     "S R\n" 
     "S R\n" 
     "Democrat Mayor Steven Markel\n" 
     "Republican Judge Matt Stevens\n" 
     "M D\n" 
     "J R\n" 
     "S R\n" 
     "S R\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"; 
    } 
} 

輸出:

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 ***** 
相關問題