コンソールアプリっていうからにはコマンドラインを解析し、与えられたオプションに基づいてそれに応じた処理を行わにゃなりません。簡単なものであれば:
int main(int argc, char* argv[]) { vector<string> args(argv, argv+argc); if ( args.size() <= 1 ) { cerr << "no input file(s). --help to see the help." << endl; return 1; } if ( args[1] == "--help" ) { usage(); // '使い方'を出力 return 0; } if ( args[1] == .... ) ...
みたいな"力技"でコマンドラインを解析するんですが、オプションが増えてくると力技では相当に面倒で複雑なコーディングを強いられます。
コマンドラインを解析してくれるライブラリといえば、Cの世界ならgetopt()が有名どころですけど、今回はいつもなにかとお世話になっているBoostライブラリ群の中の一つ、program_optionsを使います。
前準備:Boostをビルドする
それではBoostのビルドから始めましょう。現時点での最新版1.54.0をダウンロードページから拾って適当なディレクトリに展開します(ここを<BOOST_ROOT>と表記します)。Windows/Visual C++であれば、コマンドプロンプト立ち上げて<BOOST_ROOT>に移動しbootstrap,続いてb2を実行すればBoostの提供する全ライブラリを片っ端からコンパイルし、<BOOST_ROOT>\stage\libに置いてくれます。生成されるライブラリはマルチスレッド・ランタイムDLL・Release/Debug(-MD/-MDd)です。
サンプル・プロジェクトをお試しの際は、環境変数BOOST_ROOTを設定してください。
Boost.program_optionsのかんたんチュートリアル
Boost.program_optionsによるコマンドライン解析は、
- options_descriptionにオプションを記述して
- parserに(1)を食わせてコマンドラインを解析し
- (2)の結果をvariables_mapから取り出す
というダンドリになります。
簡単な例をいくつか紹介しましょう。例えば小さなコンパイラ:myccを作るとしましょうか。コマンドライン文法はこんなカンジで:
- - mycc foo.c bar.c:foo.c,bar.cをコンパイルし実行形式を作る
- - mycc -O2 ... :最適化レベルを2にする(デフォルト値は0)
- - mycc -I../include ...:インクルード・パス設定(複数設定可)
- - mycc --help:ヘルプを出力する
いちばん単純な、オプションスイッチ(-,--から始まる識別子)に後続するオプション値を持たない(上記では--help)場合。
#include <iostream> #include <boost/program_options.hpp> namespace po = boost::program_options; using namespace std; int main(int argc, char* argv[]) { try { // オプションを記述して po::options_description desc("オプションの説明"); desc.add_options() ("help,h" , "ヘルプの出力") ; // parserに食わせ po::command_line_parser parser(argc,argv); parser.options(desc); // 解析結果を variables_map に格納し po::variables_map vm; po::store(parser.run(), vm); po::notify(vm); // 結果を読み出す if ( vm.count("help") ) { cout << "mycc [option]... <input_file>...\n" << desc << endl; } return 0; } catch(exception& e) { cerr << "error: " << e.what() << "\n"; } catch(...) { cerr << "Exception of unknown type!\n"; } return 1; }
variables_mapはstd::mapから導出されているので、count()メンバ関数で指定したオプションがコマンドラインに指定されたかを知ることができます。また、options_descriptionをストリームに<<するとヘルプが出てくる親切設計。