【问题标题】:C++ Reading Multiple Variables from Text LineC++ 从文本行读取多个变量
【发布时间】:2016-09-14 14:15:33
【问题描述】:

我对 C++ 很陌生,我有一个关于读取文本文件数据的问题。

我有一个包含如下数据集的文本文件:

The Undertaker 4 3 2 6 
John Cena 22 19 8 5
Kurt Angle 5 9 33 17

我用来阅读的代码是

for(int i=0; i<numWrestlers; i++)
{
    getline(infile, firstName, " ");
    getline(infile, lastName, " ");
    for(j=1; j<4; i++) 
         {
         getline(infile, score[i], " ")
         }
}

但有时文件的行看起来像:

Rob Van Dam 45 65 35 95
Hitman Bret Hart 34 9 16
Hulk Hogan 9

我不知道如何处理这些条目。任何帮助将不胜感激,如果这是一个重复的问题,请链接原件。谢谢

【问题讨论】:

  • 您可能会喜欢Boost::Spirit。解析是一项复杂的业务。
  • 如果我理解正确你想从文本文件中访问每个变量?

标签: c++ file text


【解决方案1】:

阅读整行,查找第一个数字并将该行分成两个子字符串,就在第一个数字之前。第一个子字符串是名称,第二个子字符串包含数字。

如何处理包含两个以上“单词”的名称取决于您,但这并不像看起来那么容易,因为有些中间名实际上不是正确的中间名,而是姓氏的一部分(如“Rob Van Dam”的例子)。

数字更容易,特别是如果您使用std::vector 来存储它们而不是固定大小的数组,那么您可以使用普通的&gt;&gt; 输入运算符从std::istringstream 中读取整数循环,然后推回向量中。

【讨论】:

    【解决方案2】:

    std::getline 设置 failbit 如果它出于某种原因没有读取任何字符。

    因此,如果设置了 failbitinfile.fail() 将返回 true,这意味着它没有正确读取值(例如,如果它们不存在)。

    【讨论】:

      【解决方案3】:

      您可以按照下面概述的思考过程

      std::string line = "";
      while(getline(file, line))
      {
        //index = first occurrence of a digit
        //split the line at index - 1
        //left_line = names, right_line = numbers
        //further processing can now be done using the left_line and right_line
      }
      

      【讨论】:

        【解决方案4】:

        这是人们一直呼吁建议的精神方法:

        namespace grammar {
            using namespace x3;
            auto name   = raw [ +(!int_ >> lexeme[+graph]) ];
            auto record = rule<struct _, Record> {} = (name >> *int_);
            auto table  = skip(blank) [record % eol];
        }
        

        诀窍是在第一个数据值之前接受单词作为名称的一部分(!int_ 完成该部分)。

        记录规则解析成Record

        struct Record {
            std::string name;
            std::vector<int> data;
        };
        

        完整演示现场

        Live On Coliru

        #include <boost/spirit/include/support_istream_iterator.hpp>
        #include <boost/fusion/include/adapt_struct.hpp>
        #include <boost/spirit/home/x3.hpp>
        
        #include <iostream>
        
        namespace x3 = boost::spirit::x3;
        
        struct Record {
            std::string name;
            std::vector<int> data;
        };
        
        BOOST_FUSION_ADAPT_STRUCT(Record, name, data)
        
        namespace grammar {
            using namespace x3;
            auto name   = raw [ +(!int_ >> lexeme[+graph]) ];
            auto record = rule<struct _, Record> {} = (name >> *int_);
            auto table  = skip(blank) [record % eol];
        }
        
        int main()
        {
            std::istringstream iss(R"(The Undertaker 4 3 2 6 
            John Cena 22 19 8 5
            Rob Van Dam 45 65 35 95
            Hitman Bret Hart 34 9 16
            Hulk Hogan 9
            Kurt Angle 5 9 33 17)");
        
            std::vector<Record> table;
        
            boost::spirit::istream_iterator f(iss >> std::noskipws), l;
        
            if (parse(f, l, grammar::table, table)) {
                for (auto& r : table) {
                    std::copy(r.data.begin(), r.data.end(), std::ostream_iterator<int>(std::cout << r.name << ";", ";"));
                    std::cout << "\n";
                }
            }
        }
        

        打印

        The Undertaker;4;3;2;6;
        John Cena;22;19;8;5;
        Rob Van Dam;45;65;35;95;
        Hitman Bret Hart;34;9;16;
        Hulk Hogan;9;
        Kurt Angle;5;9;33;17;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-15
          • 1970-01-01
          • 1970-01-01
          • 2018-09-29
          • 2011-10-24
          • 1970-01-01
          相关资源
          最近更新 更多