将CSV解析为struct Array

时间:2017-12-01 22:23:47

标签: c++ arrays csv parsing struct

我正在尝试将CS​​V解析为结构数组。分隔符是&#39 ;;'。如果您查看代码,我似乎只填充了九个数组的第一个元素,现在我的CSV中有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;

我正确地全局初始化了结构,并且还有fstreams。希望它足够了。感谢

enter image description here

1 个答案:

答案 0 :(得分:0)

我建议使用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