C ++从文本行读取多个变量

时间:2016-05-18 08:07:36

标签: c++ file text

我对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

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

4 个答案:

答案 0 :(得分:6)

这是人们一直在吵着要建议的精神方法:

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;

答案 1 :(得分:2)

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

如何使用两个以上的单词来处理姓名&#34;在它们中取决于你,但它并不像看起来那么容易,因为一些中间名实际上并不是中间名,而是姓的一部分(如#34; Rob的例子中所示)范大坝&#34;)。

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

答案 2 :(得分:2)

您可以按照下面列出的思维过程进行操作

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
}

答案 3 :(得分:0)

std::getline如果因任何原因没有读取任何字符,则会设置failbit

因此,如果设置了infile.fail()true将返回failbit,这意味着它没有正确读取值(例如,如果它们不在那里)。< / p>