【问题标题】:How to parse line-by-line using ifstream [closed]如何使用 ifstream 逐行解析 [关闭]
【发布时间】:2017-12-04 02:51:17
【问题描述】:

如果我想逐行解析文件并将数据存储在单独的变量中,使用 getline 存储到字符串中并解析/转换为单独的变量似乎是一个很长的路要走。例如,对于“ABC a1 1 2 3”行,如果我想将前两个数据存储为字符串,其余三个数据存储为整数,那么从文件中逐行读取的有效方法是什么?相应地存储它?

【问题讨论】:

  • C++ 并不以拥有一堆快捷方式而著称,这些快捷方式使事情变得又快又容易。使用std::getline(),然后解析每一行,是最轻松、最简单的方法。 stackoverflow.com 上充斥着无尽的、燃烧的残骸,这些残骸是由于尝试使用格式化提取 >> 运算符来处理面向行的输入而导致的。不要这样做。 std::getline() 是你的朋友。学习它。喜欢它。
  • 老实说,在我看来,我认为您应该将其存储在 vector<string> 中,然后使用它来解析个人 strings:stackoverflow.com/q/32991193/2642059 但由于问题的模糊性,我不能保证这是正确的答案。
  • 如果每一行都有相同的表示,while(cin >> s1 >> s2 >> i1 >> i2 >> i3) save values; 是一种方式。
  • 上述方法效果最好。谢谢

标签: c++ parsing ifstream


【解决方案1】:

Boost.Spirit 适合用您自己的语法解析自定义数据格式。

#include <iostream>
#include <sstream>
#include <string>
#include <tuple>

#include <boost/fusion/include/std_tuple.hpp>
#include <boost/spirit/home/x3.hpp>

std::tuple<std::string, std::string, int, int, int>
parse(std::string const &input)
{
    auto iter = input.begin();

    using namespace boost::spirit::x3;

    auto name = rule<class name, std::string>{}
        = lexeme[upper >> *upper];
    auto ident = rule<class ident, std::string>{}
        = lexeme[alpha >> *alnum];

    std::tuple<std::string, std::string, int, int, int> result;

    bool r = phrase_parse(iter, input.end(),
                          name > ident > int_ > int_ > int_,
                          space, result);

    if (!r || iter != input.end())
    {
        std::string rest(iter, input.end());
        throw std::invalid_argument("Parsing failed at " + rest);
    }

    return result;
}


int main()
{
    // This could be a file instead with std::ifstream
    std::istringstream input;
    input.str("ABC a1 1 2 3\nDEF b2 4 5 6\n");

    for (std::string line; std::getline(input, line); )
    {
        std::string name, ident;
        int a, b, c;
        std::tie(name,ident,a,b,c) = parse(line);

        std::cout << "Found the following entries:\n"
                  << "Name: " << name << "\n"
                  << "Identifier: " << ident << "\n"
                  << "a: " << a << "\n"
                  << "b: " << b << "\n"
                  << "c: " << c << "\n";
    }
}

Live example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 2013-10-22
    • 2011-08-09
    • 2015-02-22
    相关资源
    最近更新 更多