YAMAGUCHI::weblog

土足で窓から失礼いたします。今日からあなたの息子になります。 当年とって92歳、下町の発明王、エジソンです。

boostでtokenize

工学系だとCSV(カンマ区切りファイル)やTSV(タブ区切りファイル)を読み込んで行列/ベクトルに突っ込むみたいなコードを書くことがしばしばあります。最近のスクリプト言語だとこういった文字列処理が得意だったりするわけですが、c++でそれを実現するときはboostのtokenizerを使うと楽ちんです。
例えばパイプ区切り(|)のファイルを読み込んでvectorに突っ込む場合。

  • ファイルの内容
this|is|a|tokenize||test
multiple|line||test
#include <iostream>
#include <string>
#include <vector>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;

int main() {
    ifstream ifs( filename );
    vector<string> strv;

    typedef tokenizer< char_separator<char> > Tokenizer;
    char_separator<char> pipe_separator("|", "", boost::keep_empty_tokens);

    while( getline(ifs, line) ) {
        Tokenizer toks(line, pipe_separator);
        copy(toks.begin(), toks.end(), back_inserter(strv));
        cerr << strv << endl;
        strv.clear();
    }
    return 0;
}
  • 結果
<this><is><a><tokenize><><test>
<multiple><line><><test>

注意しなければいけないのは、デフォルトでは空要素は無視されるということ。空要素を無視させないためには char_separatorのコンストラクタで boost::keep_empty_tokens を引数に与えないといけないこと。

*1:サンプルコード中のvectorの<<演算子は実装されている物とします