C++
CSV
boost

boost::tokenizerでcsvをパースしてみました。

C++における定番のcsvパーサーは?

C++csvファイルをパースするライブラリってないのかと思ってぐぐってみたが、
あまり「コレだ!」というのがなかったのでとりあえずboostを試してみました。

こんな感じになりました。

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <boost/tokenizer.hpp>


std::vector < std::vector< std::string > > parse_csv(const char* filepath)
{
    std::vector< std::vector< std::string > > cells;
    std::string line;
    std::ifstream ifs(filepath);

    // csvを走査
    while (std::getline(ifs, line)) {

        std::vector< std::string > data;

        // 1行を走査
        boost::tokenizer< boost::escaped_list_separator< char > > tokens(line);
        for (const std::string& token : tokens) {
            data.push_back(token);
        }

        // 1行読み込んだ結果を入れる
        cells.push_back(data);
    }

    return cells;
}



int main(void)
{
    const auto cells = parse_csv("test.csv");
    for (const auto& rows : cells) {
        for (const auto& cell : rows) {
            std::cout << "<" << cell << "> " << std::endl;
        }
        std::cout << std::endl;
    }

    return 0;
}

実行環境

OS: ubuntu16.04LTS
コンパイラ: clang++ 5.0.0

入力と結果

入力
2017,"hoge",,field 1
2018,"huga",,field 4649
結果
<2017> 
\<hoge> 
<> 
\<field 1> 

<2018> 
\<huga> 
<> 
\<field 4649> 

感想

エラーハンドリングなしで書いたのでめちゃくちゃ簡単でした。
まあエラーハンドリングを書いたところで大してコードは膨らまないと思いますが。

参考

http://www.boost.org/doc/libs/1_66_0/libs/tokenizer
http://kaworu.jpn.org/cpp/boost::tokenizer%E3%81%A7CSV%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80