【问题标题】:Parsing txt files in cpp在cpp中解析txt文件
【发布时间】:2022-01-05 14:25:14
【问题描述】:

我正在尝试解析一个 txt 文件以获取信息并使用 c++ 创建一个对象。

以下是该文件包含的几行示例:

Angelic Page,1,1,1,creature,nothing;
Auramancer,2,2,2,creature, nothing;
Dauntless Cathar,2,3,2,nothing;
Fencing Ace,1,1,1,nothing;
Ace aux poings ardents,3,5,5,Human,nothing;
Roronoa Zoro,5,7,7,Demon,nothing;

我想用这些信息创建一个对象卡:

Carte::Carte(std::string name, int cost, int pv, int attack, std::string type, std::string capacity)
{
    std::cout << "\tCreation d'une carte\n\n" << std::endl;
    this->m_name = name;
    this->m_cost = cost;
    this->m_pv = pv;
    this->m_strength = attack;
    this->m_type = type;
    this->m_capacity = capacity;
}

这是我尝试过的:

std::vector<Carte> Carte::generateCard(std::string nomFichier)
{
    std::string txtCard;

    std::ifstream readFile(nomFichier);

    std::vector<std::string> cardVec;

    while (std::getline(readFile, txtCard, ';')) {
        cardVec.push_back(txtCard);
    }

    readFile.close();

    std::vector<std::vector<std::string>> vecVecCard;

    for (std::string s : cardVec) {
        std::istringstream stream;
        std::vector<std::string> vecCard;
        stream.str(s);

        for (std::string line; std::getline(stream, line, ','); ) {
            vecCard.push_back(line);
        }
        vecVecCard.push_back(vecCard);
    } 
    
    std::vector<Carte> finalVectorCard;
    
    for (std::vector<std::string> v : vecVecCard) {
        std::string tabTemp[6];

        for (int i = 0; i < v.size(); i++) {
            tabTemp[i] = v.at(i);
        }
        
        try {
            Carte(tabTemp[0], std::stoi(tabTemp[1]), std::stoi(tabTemp[2]), std::stoi(tabTemp[3]), tabTemp[4], tabTemp[5]);
            finalVectorCard.push_back(c);
        }
        catch (std::invalid_argument const& e) {
            std::cout << "Bad input: std::invalid_argument thrown" << std::endl;
        }
        catch (std::out_of_range const& e) {
            std::cout << "Integer overflow: std::out_of_range thrown" << std::endl;
        }
        
    }

    return finalVectorCard;

我的逻辑是:

  • first : 用定界字符 ';' 解析--> 返回一个带有类似 ' 的字符串的向量 Auramancer,2,2,2,creature, nothing'
  • second : 用分隔符',' 解析 --> 返回向量的向量
  • 创建一个对象并将其存储在一个向量中,然后返回这个向量。

这不起作用。 当我创建一张卡片时,它会立即被销毁。我有点迷茫。

【问题讨论】:

  • 如果您可以控制文本文件的格式,那么让它更“机器可读”会容易得多。您目前有两个不同的分隔符,逗号和分号。这会造成不必要的工作。
  • @sweenish 我确实有控制权!但是如何区分两个单词之间和两个不同对象之间的简单定界呢?这就是为什么我放分号
  • 似乎每个对象总是有相同数量的字段。这是一个好的开始。
  • 仅供参考,当方法参数与成员变量同名时,您只需要this-&gt; 语法。尝试删除构造函数中的 this-&gt; 文本,看看会发生什么。更少的打字意味着更少的打字错误。

标签: c++ file parsing txt


【解决方案1】:

Carte 被销毁,因为他在push_back 之后超出范围

for (/*...*/) {
    Carte c = Carte(tabTemp[0], std::stoi(tabTemp[1]), std::stoi(tabTemp[2]),
        std::stoi(tabTemp[3]), tabTemp[4], tabTemp[5]);
    finalVectorCard.push_back(c);
}
// out of scope

为什么?

在您的 for 循环的每次迭代中,c 都会被销毁,因为程序不再需要它。

如何解决

你有两个选择:

  • emplace_back:直接在你的std::vector&lt;Card&gt; 中构造Carte
  • std::move:将c使用的实际内存移动到你的std::vector
// emplace_back implementation:
finalVectorCard.emplace_back(tabTemp[0], std::stoi(tabTemp[1]),
    std::stoi(tabTemp[2]), std::stoi(tabTemp[3]), tabTemp[4], tabTemp[5]));

// std::move implementation:
Carte c = Carte(tabTemp[0], std::stoi(tabTemp[1]), std::stoi(tabTemp[2]), std::stoi(tabTemp[3]), tabTemp[4], tabTemp[5]);
finalVectorCard.push_back(std::move(c));

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多