How to read input from the text file until/after a specific location [C++]?

跟風遠走 提交于 2021-02-08 12:11:17

问题


In my Project I need to get data about circuit from a text file then I need to parse it and produce to output data. Here is a sample data for the text file

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

AND2 Adder1-4 Adder1-2

OR1 AND1-1 AND2-1 //OR1's two inputs are from AND1's 1st output and AND2's 1st output

now I need to read the component name first which is easy:

infile>>componentName;

But for the second part I though I could to this in to ways

  1. Read the whole data and seperate it into two parts : ComponentName - thOutput.
  2. Read until "-" and put it into string variable then read after "-" and put it into integer variable and repeat this for all lines.

I tried the first way but I really stuck at converting string into integer (I tried using stoi but its for C++ only :( and also encountered with couple of problems) but I though the second way would be much easier but I couldn't figure it how to do it.

So can you help me with this ? Basicly I need to put component name(before "-") into string variable and put the integer (after "-") into integer variable.

NOTE: Sorry for my poor English not a Native Speaker. and since the Project is large I didn't put unnecessary codes above.


回答1:


This is rather basic, but should get you started. I prefer the scanf family for these tasks.

#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);

}

Output Produced for AND2 Adder1-4 Adder1-2:

AND2
Adder1
4
Adder1
2



回答2:


You could use Boost.Spirit for this parsing task. It allows you to parse the result directly into a struct.

#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



来源:https://stackoverflow.com/questions/47638243/how-to-read-input-from-the-text-file-until-after-a-specific-location-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!