如何从文本文件读取输入到特定位置之前/之后[C ++]?

时间:2017-12-04 16:54:53

标签: c++ text-parsing

在我的项目中,我需要从文本文件中获取有关电路的数据,然后我需要解析它并生成输出数据。 以下是文本文件的示例数据

  

AND1 Adder1-3 Adder1-4 //表示AND1门从中获取第一个输入   Adder1的第三个输出和第二个输入来自Adder1的第四个输出

     

AND2 Adder1-4 Adder1-2

     

OR1 AND1-1 AND2-1 // OR1的两个输入来自AND1的第一输出   AND2的第一个输出

现在我需要首先阅读组件名称,这很容易:

infile>>componentName;

但是对于第二部分我虽然可以这样做但

  1. 阅读整个数据并将其分为两部分:ComponentName - thOutput。
  2. 阅读直到" - "并将其放入字符串变量然后读取     在" - "并将其放入整数变量并重复此操作     线。
  3. 我尝试了第一种方法,但我真的坚持将字符串转换为整数(我尝试使用stoi但它只用于C ++ :(并且还遇到了几个问题)但我虽然第二种方式会容易得多但我无法和#39;弄清楚如何做到这一点。

    那么你可以帮助我吗? 基本上我需要将组件名称(在&#34; - &#34;之前)放入字符串变量中,并将整数(在&#34; - &#34;之后)放入整数变量。 < / p>

    注意:抱歉我的英语不好,不是母语人士。由于项目规模很大,我没有把不必要的代码放在上面。

2 个答案:

答案 0 :(得分:1)

这是相当基本的,但应该让你开始。我更喜欢scanf家庭来完成这些任务。

#include <stdio.h>
#include <iostream>

using namespace std;
int main() {
FILE *fp=fopen("tmpfile", "r");
char oper[5], dev1[10], dev2[10];
int op1, op2;
fscanf(fp, "%s %[^-]-%d %[^-]-%d", oper, dev1, &op1, dev2, &op2);
cout<<oper<<endl;
cout<<dev1<<endl;
cout<<op1<<endl;
cout<<dev1<<endl;
cout<<op2<<endl;
fclose(fp);

}

AND2 Adder1-4 Adder1-2生成的输出:

AND2
Adder1
4
Adder1
2

答案 1 :(得分:0)

您可以使用Boost.Spirit进行此解析任务。它允许您将结果直接解析为结构。

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

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

struct Entry
{
    std::string op;
    std::string dev1;
    int n1;
    std::string dev2;
    int n2;
};

BOOST_FUSION_ADAPT_STRUCT(
    Entry,
    op,
    dev1, n1,
    dev2, n2)

Entry parse(std::string const &input)
{
    auto iter = input.begin();

    using namespace boost::spirit::x3;

    auto op = rule<class op, std::string>{}
    = lexeme[upper >> *(upper | digit)];
    auto dev = rule<class dev, std::string>{}
        = lexeme[upper >> *alnum];

    Entry result;

    bool r = phrase_parse(iter, input.end(),
                          op > dev > lit('-') > int_ > dev > lit('-') > int_,
                          space, result);

    if (!r)
    {
        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(
"AND1 Adder1-3 Adder1-4 // Means AND1 gate gets its first input from Adder1's 3rd output and its second input from Adder1's 4th output\n"
"AND2 Adder1-4 Adder1-2\n"
"OR1 AND1-1 AND2-1 //OR1's two inputs are from AND1's 1st output and AND2's 1st output\n");

    for (std::string line; std::getline(input, line); )
    {
        Entry e = parse(line);

        std::cout << "Found the following entries:\n"
                  << "  Operation: " << e.op << "\n"
                  << "  Device 1: " << e.dev1 << "-" << e.n1 << "\n"
                  << "  Device 2: " << e.dev2 << "-" << e.n2 << "\n";
    }
}

Live example