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

C++ c++;使用BOOST/STL/etc从文件中读取格式化的表格数据,c++,boost,stl,C++,Boost,Stl,对于我来说,为表格文本文件创建格式化数据读/写函数的最佳方法是什么。比如说: readElement(i,j) insertRow(elem[]) readColHeaders() 我想知道是否有任何现有的包装可以做到这一点 内部格式为制表符间距数据或CSV Thnx Egon有很多csv阅读器,但我从来没有找到好东西 最简单的方法是使用boost::tokenize填充文件中的向量。更奇特的方法是使用boost::spirit(但学习曲线是过山车) 要生成一个文件,在向量上进行迭代非常简单。如

对于我来说,为表格文本文件创建格式化数据读/写函数的最佳方法是什么。比如说:

readElement(i,j)

insertRow(elem[])

readColHeaders()

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

内部格式为制表符间距数据或CSV


Thnx Egon有很多csv阅读器,但我从来没有找到好东西

最简单的方法是使用boost::tokenize填充文件中的向量。更奇特的方法是使用boost::spirit(但学习曲线是过山车)

要生成一个文件,在向量上进行迭代非常简单。

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

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

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

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

    // end parse rule
    space,
    vec);`
<> P>以上的精神实例:

< P>没有C或C++的“标准”CSV阅读器/作者。这并不意味着你找不到一些预先存在的库代码来使用,但是没有一个库来管理它们。在我的工作中,我们大量使用csv文件,因此我继续使用自己的文件,以便尽可能适合我的工作流程。我可以告诉你我在我的图书馆里做过的一些事情,如果你想做自己的事情,效果相当不错:

  • 我将数据作为boost::any向量的向量保存。我让用户指定构造函数中的数据格式,类似于将格式传递给scanf的方式。这使得用户不必进行自己的强制转换。我使用boost::tokenize和boost::lexical_cast来进行实际的拆分和转换。如果您的csv文件无法放入内存,这显然不会很好地工作,但这对我来说很少是一个问题

  • 我可以有一个模板化的get(),它执行any_强制转换并返回正确的数据

  • 我将列名散列到它们的索引中,以便支持按列名查找,而不仅仅是位置查找

  • 我允许用户指定一些列组合的“主键”,然后保留一个散列,这样对于每一行,您都有一个键->行号中值的映射。例如,如果您正在读取股票数据,您可能希望根据CUSIP或股票代码查找行,而不是在整个数据上交互查找行

  • 让用户指定一个大小提示,以便您可以在存储中保留()

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

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

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


不是为了讨论语言,但这个库实际上是我最初在perl中所做的事情的一个端口,如果它在perl中编写起来不容易10倍,使用起来也不友好10倍,那就糟糕了。如果你能帮助,我不建议在C++中做CSV处理。< /P> < P>将一个制表符分隔的表读入字符串向量的向量…< /P>
#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;
}
#包括
#包括
#包括
#包括
typedef std::vector StringVec;
typedef std::vector RowVec;
RowVec readRows(标准::istream&f){
std::字符串行;
RowVec行;
while(std::getline(f,line)){
rows.push_back(StringVec());
std::字符串条目;
std::istringstream linestrm(线路);
while(std::getline(linestrm,条目'\t')){
rows.back().push_back(条目);
}
}
返回行;
}
int main(){
std::istringstream文本文件(“a\tb\tc\n1\t2\t3”);
RowVec rows=readRows(textFile);
标准::cout