LoginSignup
14
5

More than 5 years have passed since last update.

C++でPythonのargparse風のものを実装した話

Posted at

手っ取り早く使ってみたい・見てみたいと思っていただける方は GitHub をご覧ください。

動機

C++でコマンドライン引数を解析できるライブラリは探してみた限りいくつかありました。
ですが、Pythonのargparseのように扱えるライブラリは自分が探した範囲では見つかりませんでした(見つかる前に諦めていたのかも)。
そこで、作れる範囲で作れば良いではないかということで勉強も兼ねて作ってみた次第であります。

作ったもの

  • C++11以降の機能を使う
  • コマンドライン引数を解析
  • -hとか--helpが来たらヘルプを表示してexit(0)
  • storestore_true、位置引数みたいなのをサポート
  • プログラム名、説明、エピローグをサポート
  • ヘルプの自動作成

GitHubのexample.cppのコピーです。

example.cpp
#include "argparse.hpp"


int main(int argc, char** argv) {
    argparse::ArgumentParser parser("test", "argparse test program", "Apache License 2.0");

    parser.addArgument({"--value", "--set-value"}, "set value");
    parser.addArgument({"--flag"}, "flag", argparse::ArgumentType::StoreTrue);
    parser.addArgument({"--value-default", "--value-with-default-value"}, "set value or use default value");

    parser.addArgument({"value1"}, "value1");
    parser.addArgument({"value2"}, "value2");

    auto args = parser.parseArgs(argc, argv);

    std::cout << std::boolalpha;
    std::cout << "value: " << args.get<std::string>("value") << std::endl;
    std::cout << "flag:  " << args.has("flag") << std::endl;
    std::cout << "value(default='abc'): " << args.safeGet<std::string>("value-default", "abc") << std::endl;

    std::cout << "value1: " << args.get<std::string>("value1")<<std::endl;
    std::cout << "value2: " << args.get<std::string>("value2")<<std::endl;
}

使い方

  1. argparse::ArgumentParserのインスタンスを作成
  2. addArgument関数を使い受け取れる引数を追加
  3. parseArgs関数を使いコマンドライン引数をパース
  4. parseArgsの返り値を受ける
  5. ほしい引数を受け取る

addArgument関数

-または--で始まる引数はキーワード引数として扱われます。
第二引数でヘルプで表示する説明を記述します。
第三引数でStoreTrueまたはStoreを指定します。StoreTrueのときはフラグになります。デフォルトではStoreとなっています。

ほしい引数を受け取る(Argumentsクラス)

コマンドライン引数を取得するときは指定した識別子から先頭の-または--を除いた名前を使います。
例えば--versionを追加した場合取得にはversionを指定します。複数指定した場合、最初に指定したものが使用されます。

has関数を使うことでコマンドライン引数に使われたかがわかります。フラグの場合はこれを使います。
非テンプレートget関数を使うことでチェックと値の取得を同時に行えます。
テンプレートget関数は存在しない値を取得しようとすると例外が発生します。
safeGet関数はデフォルトの値を指定できます。

おわりに

PythonとC++の違いで妥協した部分も多々ありますが、使っていただけると幸いです。

14
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
5