c ++使用BOOST / STL / etc从文件中读取格式化表格数据

时间:2011-02-24 13:22:20

标签: c++ boost stl

为表格文本文件创建格式化数据读取/写入功能的最佳方法是什么?说一些电话,如:

readElement(i,j)

insertRow(elem[])

readColHeaders()

我想知道现有的包装器是否可以做到这一点?

内部格式是标签间距数据或CSV。

日Thnx-埃贡

4 个答案:

答案 0 :(得分:3)

有很多csv读者,但我从来没有找到好的东西。

最简单的方法是使用boost :: tokenize填充向量< vector< string> >从你的文件。更高级的方法是使用boost :: spirit(但学习曲线是过山车)。

要生成文件,请迭代向量< vector< string> >是非常微不足道的。

答案 1 :(得分:1)

C或C ++没有“标准”csv读/写器。这并不意味着你找不到一些预先存在的库代码,但没有一个库可以统治它们。在我的工作中,我们大量使用csv文件,所以我继续推进自己的工作,以便尽可能地适应我的工作流程。我可以告诉你我在我的图书馆里做的一些事情已经做得相当好,如果你想做自己的事情:

  • 我将数据保存为boost :: any的向量向量。我让用户指定构造函数中数据的格式,类似于将格式传递给scanf的方式。这使用户不必进行自己的演员表。我使用boost :: tokenize和boost :: lexical_cast进行实际的拆分和转换。如果你的csv文件不能适合内存,这显然不会很好用,但这对我来说很少有问题。

  • 我可以使用模板化的get()来执行any_cast并返回正确的数据。

  • 我在索引中有一个列名哈希,以便按列名支持查找而不仅仅是位置查找

  • 我允许用户指定某些列组合的“主键”,然后保留一个哈希,使得每行都有一个键中值的映射 - >行号。例如,如果您正在阅读股票数据,您可能希望根据CUSIP或股票代码找到该行,而不是整合整个数据以查找您的行。

  • 让用户指定尺寸提示,以便您可以在存储空间中保留()

  • 让用户指定回调函数,以便他可以在读/写时处理和过滤他不想要的行

  • 允许用户指定在读/写时是否需要锁定文件

  • 允许用户为文件中没有标题的文件传入自己的列标题

不要进入语言辩论,但是这个库实际上是我最初在perl中做过的一个端口,并且如果写入不容易10倍,并且在perl中使用的用户友好性高10倍,该死的话。如果你能提供帮助,我不建议你用C ++进行csv处理。

答案 2 :(得分:1)

将制表符分隔的表读入字符串向量的向量...

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

typedef std::vector<std::string> StringVec;
typedef std::vector<StringVec> RowVec;

RowVec readRows(std::istream& f) {
    std::string line;
    RowVec rows;
    while (std::getline(f, line)) {
        rows.push_back(StringVec());
        std::string entry;
        std::istringstream linestrm(line);
        while (std::getline(linestrm, entry, '\t')) {
            rows.back().push_back(entry);
        }
    }
    return rows;
}

int main() {
    std::istringstream textFile("a\tb\tc\n1\t2\t3");
    RowVec rows = readRows(textFile);
    std::cout << rows.size() << std::endl;
    std::cout << rows[0][0] << std::endl;
    std::cout << rows[1][2] << std::endl;
    return 0;
}

答案 3 :(得分:0)

如果您的数据很小(例如小于几百兆字节),我会将整个文件读入内存。为此,您可以将其存储在boost::numeric::ublas::matrix<std::string>之类的字符串矩阵或std::vector<std::vector<std::string> >

之类的向量中。

Boost.Spirit提供了一种非常好的方法来将这种类型的文本数据解析为这些结构。这归结为一个解析命令,如:

boost::spirit::qi::phrase_parse(
    begin,
    end, 
    // parse rule:

        *(char_ - '\t') % '\t' 

    // end parse rule
    space,
    vec);`

此处有更多精神示例:http://www.boost.org/doc/libs/1_46_0/libs/spirit/doc/html/spirit/qi/tutorials.html