[ C++で開発 ] [ Boostを使うメモ ]
コマンドラインから実行するプログラムでは、コマンドライン引数に指定した内容を取り込む処理を記述することが多いです。引数の数が数個と少ない場合は、大抵その場限りのコーディングでお茶を濁しますが、ちょっと複雑なコマンドラインとなると、やはりライブラリの出番となります。
昔はCの非標準ライブラリ getopt の出番だったのですが、最近ではBoostに含まれる program_options を使用します。
簡単なサンプルを示します。
コマンドラインで、以下3つのオプションを指定可能なプログラム mcast_send があったとします。
以下の書式で使用するものとします。
$ mcast_send -a ff3e:20:2001:db8::101 -p 30000 -i eth0
#include <boost/program_options.hpp> #include <string> using boost::program_options::options_description; using boost::program_options::value; using boost::program_options::variables_map; using boost::program_options::store; using boost::program_options::parse_command_line; using boost::program_options::notify; int main(int argc, char* argv[]) { options_description opt("オプション"); // 引数の書式を定義 opt.add_options() ("help,h", "ヘルプを表示") ("address,a", value<std::string>(), "マルチキャストアドレス") ("port,p", value<int>(), "ポート番号") ("interface,i", value<std::string>(), "インタフェース名"); // 引数の書式に従って実際に指定されたコマンドライン引数を解析 variables_map argmap; store(parse_command_line(argc, argv, opt), argmap); notify(argmap); // ヘルプ表示指定があるか、必須引数が抜けていた場合、ヘルプ表示して終了 if (argmap.count("help") || !argmap.count("address") || !argmap.count("port")) { std::cerr << opt << std::endl; return 1; } // コマンドライン引数から変数に取り込み std::string address = argmap["address"].as<std::string>(); int port = argmap["port"].as<int>(); const char* interface = 0; if (argmap.count("interface")) { interface = argmap["interface"].as<std::string>().c_str(); } : } |
ヘルプ表示は以下の出力となります。
オプション: -h [ --help ] ヘルプを表示 -a [ --address ] arg マルチキャストアドレス -p [ --port ] arg ポート番号 -i [ --interface ] arg インタフェース名
boost::program_optionsは、ライブラリをリンクする必要があります。
コマンドラインオプションを未指定時に、デフォルト値を適用する場合、以下のようにdefault_valueを指定します。
("port,p", value<int>()->default_value(8080), "ポート番号")
コマンドラインオプションの解析でエラーがあると、例外がスローされます。例外はstd::exceptionのサブクラスなので、これを捕捉します。
try { store(parse_command_line(argc, argv, opt), argmap); } catch (std::exception& ex) { std::cerr << "コマンドライン引数の指定に誤りがあります: " << ex.what() << std::endl << opt << std::endl; throw; }
ファイルからオプションを読み込むことができます。
std::ifstream inFile("mcast.conf"); store(parse_config_file(inFile, opt), vm);
ファイルの書式は、
# mcast_send/receive configuration file port = 8087 if = 2 # address = ff3e:20:2001:db8::101
行の先頭に#があると、コメントとして扱われます。
(要確認)ファイルとコマンドラインとは、先に解析した方が優先されます。