【问题标题】:Parsing CSV into Struct Array将 CSV 解析为结构数组
【发布时间】:2018-05-16 02:06:23
【问题描述】:

我正在尝试将 CSV 解析为结构数组。分隔符是';'。如果您查看代码,似乎我现在在我的 CSV 中只填充了 9 行中的数组的第一个元素,即 9 行。数组的剩余元素只有 0。有人有什么建议吗?谢谢

fileTO.open("imput.csv", ios_base :: app);
fileFROM.open("imput.csv", ios_base :: app);

//IntoCsvThruConsole();

// array of structures from csv

string line;

string sID, stype, scategory, samount, sdate;

int lines = CountExistingLines();

Properties * structure = new Properties[lines];
int counter = 0;
int position = 0;

while (getline(fileFROM, line))
    {
        sID = "";
        samount = "";

     for (int i = 0; i < line.size(); i++)
     {
      if (line[i] == ';')
      {
          position++;
          continue;
      }
      switch (position)
      {
          case 0 : sID = sID + line[i];
          break;

          case 1 : structure[counter].type = structure[counter].type + line[i];
          break;

          case 2 : structure[counter].category = structure[counter].category + line[i];
          break;

          case 3 : samount = samount + line[i];
          break;

          case 4 : structure[counter].date = structure[counter].date + line[i];
          break;
      }
     }
     structure[counter].ID = atoi(sID.c_str());
     structure[counter].amount = atoi(samount.c_str());

    cout << "ID zaznamu: " << structure[counter].ID << endl;
    cout << "Typ: " << structure[counter].type << endl;
    cout << "Kategorie: " << structure[counter].category << endl;
    cout << "Castka: " << structure[counter].amount << endl;
    cout << "Datum: " << structure[counter].date << endl;

    counter++;
    }

delete[] structure;

我已经正确地全局初始化了 struct 和 fstreams。希望这就足够了。谢谢

enter image description here

【问题讨论】:

  • 你能再深入一点吗?
  • 你应该使用向量而不是一个字符一个字符。要我发布解决方案吗?
  • 半相关:这个for循环for (int i = 0; i &lt; line.size(); i++)几乎可以完全替换为std::stingstream stream(line);和一堆像std::getline(stream, sID, ';');这样的行来读取标记。
  • @user4581301 这就是我要说的!
  • 非常接近的例子:stackoverflow.com/a/20303099/4581301 实际上,我打算将此作为欺骗。

标签: c++ arrays csv parsing struct


【解决方案1】:

我建议将 Boost.Spirit 用于此类解析任务。

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

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

struct Date
{
    int day;
    int month;
    int year;
};

std::ostream& operator<<(std::ostream& os, Date const &d)
{
    os << d.day << '/' << d.month << '/' << d.year;
    return os;
}

BOOST_FUSION_ADAPT_STRUCT(
    Date,
    day, month, year)

struct Properties
{
    int ID;
    std::string type;
    std::string category;
    int amount;
    Date date;
};

BOOST_FUSION_ADAPT_STRUCT(
    Properties,
    ID, type, category, amount, date)

std::vector<Properties> parse(std::string const &input)
{
    auto iter = input.begin();

    using namespace boost::spirit::x3;

    auto name = rule<class name, std::string>{}
        = lexeme[alpha >> *alpha];

    auto date = rule<class date, Date>{}
        = int_ > '/' > int_ > '/' > int_;

    std::vector<Properties> result;

    bool r = phrase_parse(iter, input.end(),
                          (int_ > ';' > name > ';' > name > ';' > int_ > ';' > date) % eol,
                          space - eol, 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(
        "1;TypeA;CategoryA;10;05/12/2017\n"
        "2;TypeB;CategoryA;21;04/12/2017\n"
        "3;TypeB;CategoryB;19;01/12/2017\n"
        "4;TypeA;CategoryA; 6;20/11/2017\n");

    std::vector<Properties> entry = parse(input.str());

    for (auto e :  entry)
    {
        std::cout << "Found the following entries:\n"
                  << "  ID: " << e.ID << "\n"
                  << "  Type: " << e.type << "\n"
                  << "  Category: " << e.category << "\n"
                  << "  Amount: " << e.amount << "\n"
                  << "  Date: " << e.date << "\n";
    }
}

Live example

【讨论】:

    猜你喜欢
    • 2018-04-07
    • 2015-05-21
    • 2021-03-13
    • 2018-02-22
    • 2017-10-26
    • 2011-08-28
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多