C++: std::vector
へのCSVデータの読み込み
概要
先日,C++でのテキストデータの一括読み込み方法を整理した。その最後に,昔はCSVファイルの読み込みに挑戦して四苦八苦したが,今ならstd::getline()
を活用すれば簡単に実現できそうだと書いた。
入力データとしてCSVは手軽でよく使われる形式なので,せっかくなので改めてC++でのCSVデータの読み込み方法を整理することにした。
実装
まずは実装例を以下に掲載する。前回同様,GitHubでも公開している。
このコードをコンパイルして実行すると,以下のようにCSVデータの要素がスペース区切りで表示される。
11 12 13 21 22 23 31 32 33
説明
前回のテキストデータの読み込み同様,std::getline()
を駆使して実装した。
CSVデータを2次元のstd::vector
に格納するために若干工夫した。肝となるのは以下の部分だ。
std::stringstream input("11,12,13\n21,22,23\n31,32,33\n");
std::vector<std::vector<std::string>> vv;
for (std::string value; std::getline(input, value);) {
vv.push_back(std::vector<std::string>());
for (std::stringstream ss(value); std::getline(ss, value, ',');) {
vv[vv.size()-1].push_back(value);
}
}
以下の手順で実装した。
素直にstd::getline()
を使って実装した。std::vector
への追加方法,要素サイズの拡大方法で少し頭を使った。その他,余計な一時変数が生まれないようにstd::string value
を使いまわした。
わかりやすさを重視するならば,2回目のfor文のvalue
は別の名前の変数にしてもよいかもしれない。
また,前回同様にstd::getline()
の第1引数のオブジェクトを以下のように変更することで,標準入力やファイルにも対応できる。
シンプルに実装できて満足だった。
結論
C++でのCSVデータのstd::vector
への読み込み方法を解説した。
CSVデータの読み込みはデータ処理の基本でもあるので,整理できたのはよかった。今回の実装例をベースに,必要に応じて型変換やデータの読み飛ばしなどを行えばよいだろう。
C++を始めたての頃は,変にPythonの知識があった分,Pythonと同じように実装しようとしてライブラリー関数を探し回ったりして遠回りをしていた。
安易に外部ライブラリーなどに頼るのではなく,C言語と同様に,基本的な処理を組み合わせて実装することが,シンプルでわかりやすいのかもしれない。
また何かよくある問題に遭遇したら整理したい。