読者です 読者をやめる 読者になる 読者になる

Boost.ProgramOptions 備忘録

ちょっとコマンドラインでぽちぽちやる必要がでてきて、解析するのがめんどくさいので Boost.ProgramOptions でも使おうと思います。

このライブラリはビルドしないと使えない(ヘッダオンリで利用できない)ので、そこは注意して下さい。

名前空間は長すぎて泣けるので省略しましょう。 example でやってる形で po にします。

#include <boost/program_options.hpp>
namespace po = boost::program_options;

コマンドラインだけでなく、hogehoge.conf などのようにファイルから読み取る事もできるらしいのですが、そこまではいらないので省略。

#include <boost/program_options.hpp>
#include <iostream>

int main(int argc, char** argv) {
  namespace po = boost::program_options;

  // オプションを記述するためのクラス
  po::options_description opt("options");

  // オプションを記述, operator() で追記していく
  // 引数は, オプション名, オプションに指定する引数の型(省略可), オプションの説明
  // オプション名は正式名の後に , で省略名を記述できる
  opt.add_options()
    ("help,h", "print helps.")
    ("option1", po::value<int>(), "option1")
    ("option3", "option3");

  // 追記も出来る
  // 変数にオプションの値を格納するように指定も可能
  int option2value;
  opt.add_options()
    ("option2", po::value<int>(&option2value), "option2");

  try {
    // コマンドラインを記述されたオプションを元にパースする
    po::store(po::parse_command_line(argc, argv, opt), values);

    // オプションの引数を格納する, これがないとオプションに指定された引数が
    // 格納されず, アクセスすると例外が発生する
    po::notify(values);

    // count で引数が指定されているかを確認する
    // ヘルプ表示, description をストリームに渡すと表示できる
    if(value.count("help")) {
      std::cout << opt << std::endl;
      return 0;
    }

    // オプションの引数がある場合 as で変換
    if(value.count("option1")) {
      std::cout << "option1 : " << values["option1"].as<int>() << std::endl;
    }
    // 格納する引数が指定されていればそこに入っている
    if(value.count("option2")) {
      std::cout << "option2 : " << option2value << std::endl;
    }
    if(value.count("option3")) {
      std::cout << "option3." << std::endl;
    }

  } catch(std::exception const& e) {
    // 実際には引数に指定されなかった値を operator[] でアクセスしようとすると
    // 例外が帰ってきたりする
    std::cerr << e.what() << std::endl;
    return -1;
  }
}

使うだけなら結構簡単ですね。

引数に指定された値が単純に as で変換できない値とかだと spirit とかで簡単な解析しなきゃいけないのかなと思ったりしました。