如何将一行分解成碎片并忽略它的一部分?

时间:2015-11-25 18:24:45

标签: c++ list file line push-back

对不起我此前并不是克莱尔。我有一个文件包含以下格式的数据

  

A(3)

     

B(4),A
  
  C(2),A
  
  E(5),A
  
  G(3),A
  
  Ĵ(8),B,H
  
  H(7),C,E,G
  
  I(6),G
  
  F(5),H
  
  ...

这些数据代表图表。

我将使用关键路径方法来计算如何通过此文本文件。

char就是这一步 int是每个任务的长度 另一个char是第一个char之前的步骤

所以我创建了类Task以读取文件,其构造函数具有以下参数

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

主要是我添加了

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
     //allTaches.push_back(line)
     //But the format needs to look like (Char, duration, <a list of> PrecedentChar)           
     //when I do 
     cout<< line << Lendl;
    it prints 
    A(3)
    B(4)
    A
    C(2)
    A
    E(5)
    A 
 }

所以我不知道该怎么做。

2 个答案:

答案 0 :(得分:1)

您可以使用正则表达式解析所需的部分,然后将其传递给Task

在使用std::regex

完成的c ++中

下面的代码将帮助您了解如何解析碎片,将它们应用于测试是一个简单的步骤,但最好由您确保概念清晰。

首先,我们需要一个抓取每个部分的正则表达式,这称为捕获组,所需要的只是使用括号

如果我们分解你拥有的东西 - 它是:

某种东西,一种我们不想要的开放式的东西,某种东西,一种我们不想要的亲密的东西,一种我们不想要的逗号,以及某种东西

在简单的正则表达式中:

(.*)\((.*)\),(.*)

但事情从未如此简单

第一个Something以开放的paren结束,所以我们想要的只是第一个开放的paren:([^(]) ^表示不,方括号[]表示每个字符

第二个东西以关闭的paren结束,所以我们有([^)])

第三个内容排除了可选的逗号,但我们可以使用(.*)然后将其分组到可选的* 中(可能有更好的方法可以执行此操作)

我们还需要为编译器双倍转义\,对正则表达式转义一次

我们还需要让人们在那里进入随机空间,以便我们在所有休息时间添加*

这导致了我们的正则表达式:

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

然后我们搜索,如果发现它将在结果中,我们可以迭代它以获得碎片。

#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;
                        }
                }
                else
                {
                        std::cout << "NO MATCH" << std::endl;
                }
        } catch (std::regex_error& e) {

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

}

答案 1 :(得分:0)

您实际上要做的是为Tache对象创建extraction operator。我假设您的代码看起来像这样:

typedef char Task;

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

您的提取运算符将是Tache的方法。它的暴力实施看起来像这样:

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

    rhs.precedentTask.clear();

    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