program_optionsの使い方
boostには、program_optionsという、コマンドライン引数やwindows iniファイルのパースに使えるライブラリがある。便利なので、使い方メモ。
main.cpp
/*! g++ -g main.cpp -l boost_program_options */ #include <boost/program_options.hpp> #include <string> #include <fstream> #include <iostream> #include <vector> namespace po = boost::program_options; using namespace std; string configFile; double x; void func(const vector<string>& args, const bool help = false){ double y; string s; po::options_description opt("options for func"); opt.add_options() ("func.y", po::value<double>(&y), "a double value") ("func.s", po::value<string>(&s), "a string value") ; if(help){ cout << opt << endl; return; } po::variables_map vm; po::store(po::command_line_parser(args).options(opt).allow_unregistered().run(), vm); ifstream ifs(configFile.c_str()); po::store(po::parse_config_file(ifs, opt, true), vm); po::notify(vm); cout << "y:" << y << endl << "s:" << s << endl; } int main(int argc, char* argv[]){ po::options_description optCmdOnly("generic options"); optCmdOnly.add_options() ("help,h", "produce this help message.") ("config,c", po::value<string>(&configFile)->default_value("test-program-options.ini"), "configuration file") ; po::options_description optCommon("config file common options"); optCommon.add_options() ("x", po::value<double>(&x), "common value") ; po::options_description optCmd; optCmd.add(optCmdOnly).add(optCommon); po::parsed_options parsed = po::command_line_parser(argc, argv).options(optCmd).allow_unregistered().run(); vector<string> additionalOptions = po::collect_unrecognized(parsed.options, po::include_positional); po::variables_map vm; po::store(parsed, vm); po::notify(vm); if (vm.count("help")) { cout << optCmd << endl; func(additionalOptions, true); return 0; } ifstream ifs(configFile.c_str()); po::store(po::parse_config_file(ifs, optCommon, true), vm); po::notify(vm); func(additionalOptions, false); cout << "x:" << x << endl; return 0; }
test-program-options.ini
x= 1.0 [func] y= 2.0 s= abcd
- boost_program_optionsをリンクする必要がある(ヘッダのインクルードだけでは使えない)
- options_descriptionクラスで、オプション項目を登録
- 変数のポインタを渡しておくと、適切な型に変換した上で、その変数にオプションの値を登録してくれる。
- デフォルト値も登録できる。
- 自動で生成されるヘルプのメッセージもここで登録。
- command_line_parserクラスのコンストラクタにコマンドライン引数を渡して初期化
- command_line_parserクラスに options_descriptionを登録
- command_line_parserクラスの allow_unregisteredで、登録されていないオプションを「スルーしろ」と指令(デフォルトでは例外を投げる)
- command_line_parserクラスのrunで、パース。parsed_optionsクラスのインスタンスが返る。
- collect_unrecognizedで、未パースコマンドライン引数を取得。これは、後続の関数等に渡して再利用出来る。
- parse_config_fileで、iniファイルをパース。
- プログラムの中でのオプションの名前は
. - となる。
- プログラムの中でのオプションの名前は
実行結果
bash-3.2$ ./a.out --help generic options: -h [ --help ] produce this help message. -c [ --config ] arg (=test-program-options.ini) configuration file config file common options: --x arg common value options for func: --func.y arg a double value --func.s arg a string value
ostreamに流すと、ヘルプメッセージになる。
bash-3.2$ ./a.out y:2 s:abcd x:1
ini ファイルのパース結果
bash-3.2$ ./a.out --x 10 --func.y 200 --func.s 1234567 y:200 s:1234567 x:10 bash-3.2$
先にパースされた値が優先される。