C ++如何使用相同的类和方法来读/写可变大小的数据

时间:2018-03-15 13:42:09

标签: c++ csv

我编写了一个具有读写方法的c ++类。这些方法从/向csv文件读取和写入行。 目前我已经实现了对具有五个元组(列)的csv文件的读写,例如 - EmpNo,EmpName,Address,Department,Manager。 类包含这5个元组作为类的成员变量。

所以基本上,在read()中,我正在使用fstream读取行并将元组值放入相应的成员变量中。类似地,对于写入,我从用户获取行数据到类成员变量并在csv文件中写入相同。

现在我想使用相同的代码来读取和编写另外一个csv文件,该文件只有五个元组中的两个元组--EngNo,EmpName。

我可以考虑维护一个变量来识别我正在读/写的CSV,因此在所有代码中都有if / else。但这看起来并不简洁。 我的方法的read()伪代码如下:

read()
{
    read EmpNo;
    read EmpName;
    If (csv_with_5_tuple == true)
    {
        read Address;
        read Department;
        read Manager;
    }
}

//Here, 'csv_with_5_tuple ' will be set when reading/writing from/to csv file of five tuples.

通过这种方法,我需要在课堂上的任何地方添加“if”条件。

有人能建议我用c ++做这个的最好方法吗?

2 个答案:

答案 0 :(得分:3)

您可以为此使用类继承。有伪代码证明了这个想法:

class csv2 {
public:
    virtual void read()
    {
        read EmpNo;
        read EmpName;
    }
};

class csv5 : public csv2
{
public:
    virtual void read()
    {
        csv2::read();

        read Address;
        read Department;
        read Manager;
    }
};

答案 1 :(得分:0)

通过使用某些vector和模板,您可以执行以下操作:

template <typename T>
std::vector<T> csv_read(std::istream& is, const std::vector<std::string T::*>& members)
{
    std::vector<T> res;
    std::string header;
    std::getline(is, header);
    while (true) {
        T obj;

        for (auto m : members) {
            is >> obj.*m;
        }
        if (!is) {
            break;   
        }
        res.push_back(obj);
    }
    return res;
}

使用类似于

const std::vector<std::string Person2::*> members = {&Person2::Name, &Person2::AgeStr};
auto persons = csv_read<Person2>(ss, members);

Demo

如果您只使用std::vector<std::vector<std::string>>

,则更简单
std::vector<std::vector<std::string>> csv_read(std::istream& is, std::size_t rowCount)
{
    std::vector<std::vector<std::string>> res;
    std::string header;
    std::getline(is, header);
    while (true) {
        std::vector<std::string> row(rowCount);

        for (auto& col : row) {
            is >> col;
        }
        if (!is) {
            break;   
        }
        res.push_back(row);
    }
    return res;
}

使用类似于

auto data = csv_read(ss, 2);

Demo