對於我爲表格文本文件創建格式化數據讀/寫功能的最佳方式是什麼?說一些調用,如:C++使用BOOST/STL/etc從文件中讀取格式化表格數據
readElement(i,j)
insertRow(elem[])
readColHeaders()
我在想,如果任何現有的包裝能做到這一點?
內部格式是製表符間隔數據或CSV。
日Thnx,埃貢·
對於我爲表格文本文件創建格式化數據讀/寫功能的最佳方式是什麼?說一些調用,如:C++使用BOOST/STL/etc從文件中讀取格式化表格數據
readElement(i,j)
insertRow(elem[])
readColHeaders()
我在想,如果任何現有的包裝能做到這一點?
內部格式是製表符間隔數據或CSV。
日Thnx,埃貢·
有很多CSV讀者,但我從來沒有發現一件好事。
最簡單的是使用boost ::記號化,以填補因您的文件矢量<矢量<串> >。更妙的方法是使用boost :: spirit(但學習曲線是過山車)。
要生成一個文件,在一個矢量上迭代<矢量<字符串> >是非常微不足道的。
如果您的數據很小(例如少於幾百兆字節),我會將整個文件讀入內存。爲此,您可以將其存儲在一個字符串矩陣像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
沒有爲C或C沒有「標準」 CSV讀/寫器++。這並不意味着你找不到一些預先存在的庫代碼來使用,但是沒有一個庫可以統治它們。在我的工作中,我們大量使用csv文件,所以我繼續推出自己的作品,儘可能適合我的工作流程。我可以告訴你一些我在我的圖書館已經制定了相當不錯做過的事情,你應該想也做自己的事:
我把數據提振向量的向量::任何。我讓用戶指定構造函數中的數據格式,類似於將格式傳遞給scanf的方式。這使用戶不必做自己的演員。我使用boost :: tokenize和boost :: lexical_cast來進行實際的分割和投射。如果你的csv文件不能適應內存,這顯然不會工作,但這對我來說很難。
我可以有一個模板get(),它執行any_cast並返回正確的數據。
我有列名的散列以他們的指數,以支持列名的樣子跌宕而不僅僅是位置看UPS
我允許用戶指定的某種組合的「主鍵」列,然後保留一個散列,以便每行都有鍵 - >行號中的值的映射。例如,如果您正在讀取股票數據,您可能希望根據CUSIP或股票代碼找到該行,而不是將整個數據進行交叉以找到您的行。
讓用戶指定大小的提示,所以你可以保留()在存儲
讓用戶指定的回調函數,使他可以處理和濾波線路,他爲你讀不希望/寫他們
允許用戶指定該文件需要讀/寫
允許用戶在自己的列標題以通爲沒有頭文件中的文件時被鎖定
不進入語言辯論,但這個庫真的是我最初在Perl中做的事情的一個端口,並且該死的如果它不是10倍容易編寫和10倍用戶友好在Perl中使用。如果可以幫助,我不建議用C++進行csv處理。
要讀取製表符分隔的表分成串矢量的矢量...
#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;
}