yohhoyの日記

技術的メモをしていきたい日記

TSV簡易パーサ@iostream

C++標準ライブラリiostreamのみで、TSV(Tab-Separated Values)形式入力データを解析する。

下記コードでは、入力ストリーム(istringstream)へ独自ロケールをimbueし、std::skipwsマニピュレータ*1動作を微調整することでTSV読み込みを実現している。独自ロケールとして、ctypeファセットのみを自作クラスtsv_ctypeに差し替えたものを用いる。同tsv_ctypeでは文字カテゴリテーブルを加工し、スペース文字(' ')は空白(whitespace)として扱わないよう変更する。

#include <vector>
#include <string>
#include <sstream>
#include <ios>     // std::skipws
#include <locale>  // std::ctype<>, std::locale

struct tsv_ctype : std::ctype<char> {
  static const mask* make_table()
  {
    static std::vector<mask> lut(classic_table(), classic_table() + table_size);
    lut[' '] &= ~space;
    return &lut[0];
  }
  explicit tsv_ctype(std::size_t refs = 0)
    : ctype(make_table(), false, refs) {}
};

std::istringstream iss("123\tHello world\t3.14");
iss.imbue(std::locale(iss.getloc(), new tsv_ctype));

int a;  std::string b;  float c;
iss >> std::skipws >> a >> b >> c;
// a = 123 / b = "Hello world" / c = 3.14

関連URL