How do I parse a line into pieces and ignore parts

2019-10-09 21:58发布

I am sorry. I wasn't clair previously. I have a file that include data in the following format











These data represent a graph.

I will use the critical path method to calculate how to get through this text file.

the char is the step the int is the length of each task the other char is step that come before the first char

So I have created the class Task to read the file and its constructor have the following parameters

    Tache::Tache(char step2, int duration, list<Task*> precedentTask)


          this->step = step2;
          this -> duration = duration; 
          for(list<Task*>::iterator it = this-> precedentTask.begin(); it != this-> precedentTask.end(); it++)
              this-> precedentTask.push_back(*it);

In the main I added

string line;
list<Task> *allTaches = new list<Task>();

  while(getline(file, line, ','))
       //I want to be able to receive the parse line from the file and add it like
     //But the format needs to look like (Char, duration, <a list of> PrecedentChar)           
     //when I do 
     cout<< line << Lendl;
    it prints 

So I am not sure to know what to do really.

The star\"
2楼-- · 2019-10-09 22:20

What you're actually looking to do here is create an extraction operator for your Tache object. I'm going to assume that your code looks something like this:

typedef char Task;

struct Tache {
    char step;
    int duration;
    list<Task> precedentTask;

Your extraction operator will be a method of Tache. It's brute force implementation will look something like this:

istream& operator>>(istream& lhs, Tache& rhs) {
    string line;

    getline(lhs, line, '\n');

    stringstream ss(line);

    ss >> rhs.step;
    ss.ignore(numeric_limits<streamsize>::max(), '(');
    ss >> rhs.duration;
    ss.ignore(numeric_limits<streamsize>::max(), ')');

    const regex re("\\s*,\\s*([a-zA-Z])");
    string precedentTasks;

    getline(ss, precedentTasks);


    transform(sregex_token_iterator(cbegin(precedentTasks), cend(precedentTasks), re, 1), sregex_token_iterator(), back_insert_iterator<list<Task>>(rhs.precedentTask), [](const string& i) {
        return i.front();

    return lhs;

Live Example

3楼-- · 2019-10-09 22:30

You can use a regular expression to parse out the pieces you need and then pass them to Task

In c++ that is done using std::regex

The code below will help you understand how to parse out the pieces, applying them to test is a simple step from there, but best done by you to make sure the concept is clear.

First we will need a regular expression that grabs each piece, this is called a capture group and all that is needed is to use parenthesis

If we break down what you have - it is:

Something, an open paren we dont want, Something, a close paren we dont want, a comma we don't want, and Something

in simple regex that would be:


But things are never so simple

The first Something ends with the open paren, so we want everything but that first open paren: ([^(]) the ^ means not, the square bracket [] means every character

The second Something ends with the close paren, so we have ([^)])

The third something excludes the optional comma, but we can use (.*) and then group the , in an optional * (There is likely a better way to do this)

We also need to double escape the \ once for the compiler and once for regex

We also need to allow for people entering random spaces in there so we add * in all breaks

This leads to our regex:

*([^(]*) *\\( *([^)]*) *\\) *(, *(.*))*

Then we search and if found it will be in the result and we can iterate it to get the pieces.

#include <iostream>
#include <string>
#include <regex>

int main()
        // std::string seq = "A(4),B";
        std::string seq = "A(4)";

        try {
                std::regex rgx(" *([^(]*) *\\( *([^)]*) *\\) *(, *(.*))*");
                std::smatch result;
                if(std::regex_search(seq, result, rgx))
                        std::cout << "Size=" << result.size() << std::endl;
                        for(size_t i=0; i<result.size(); ++i)
                                std::cout << result[i] << std::endl;
                        std::cout << "NO MATCH" << std::endl;
        } catch (std::regex_error& e) {

                std::cout << "BAD REGEX" << std::endl;

登录 后发表回答