サブロウ丸

主にプログラミングと数学

master mind by c++; part6 argument parser

今回やること

コマンドライン引数を受け取る部分(argument parser)の実装.

argparse

google検索で一番上に出てきたので, 使ってみる.

install

git clone でコードをダウンロードするだけ. あとはコンパイル時にインクルードディレクトリに追加します.

$ mkdir source
$ cd source && git clone https://github.com/p-ranav/argparse
add_executable(
  mastermind
  main.cpp
  )

target_include_directories(  # ここを追加!!
  mastermind PUBLIC
  ${PROJECT_SOURCE_DIR}/source/argparse/include
  )

target_compile_options(
  mastermind PUBLIC
  -Wall
  )

target_compile_features(
  mastermind PUBLIC
  cxx_std_17
  )

ちなみにp-ranav/argparseは -std=c++17以上に対応しています.

プログラムへの反映

main関数の冒頭に下記を挿入. 使い方はpythonのargument parserに似ていますね. githubのreadmeが丁寧なので, これを見れば使い方は大体わかります.

下記ではピンの色(整数), ピンの個数(整数), 色の重複を許すかどうか(bool)を受け付けています.

int main(
      int argc,
      char *argv[]
      )
{
   // argument parser
   argparse::ArgumentParser program("master mind");

   // ピンの色数
   program.add_argument("num_colors")
      .help("number of colors")
      .action([](const std::string& value) { return std::stoi(value); });

   // ピン数
   program.add_argument("num_pins")
      .help("number of pins")
      .action([](const std::string& value) { return std::stoi(value); });

   // 色の重複の有無
   program.add_argument("--no_duplicated")
      .help("secret codes donot have color duplication")
      .default_value(false)
      .implicit_value(true);
   try
   {
      program.parse_args(argc, argv);
   }
   catch (const std::runtime_error& err)
   {
      std::cout << err.what() << std::endl;
      std::cout << program;
      exit(0);
   }

   int nColors = program.get<int>("num_colors");
   int nPins = program.get<int>("num_pins");
   bool duplicate = !program.get<bool>("--no_duplicated");

   // create config object
   Config config(nColors, nPins, duplicate);
   std::cout << config.str() << std::endl;
   exit(0);

受け取ったパラメータはConfigクラスで保存.

/**
 * パラメータ管理
 */
class Config
{
   public:
      int nColors;      // number of colors
      int nPins;        // number of pins
      bool duplicate;   // if it is true, then color-duplication is allowed

      /**
      * @brief Constructor
      * @param[in] inNColors 色数
      * @param[in] inNPins ピン数
      * @param[in] inDuplicate 色の重複を許すかどうか
      */
      Config(
            int inNColors,
            int inNPins,
            bool inDuplicate
            )
         :
            nColors(inNColors),
            nPins(inNPins),
            duplicate(inDuplicate)
      {}

      /**
      * @brief 管理情報をstringにする
      * @return std::string
      */
      std::string str()
      {
         std::ostringstream os;
         os << "Config:" << std::endl;
         os << "  nColors: " << nColors << std::endl;
         os << "  nPins: " << nPins << std::endl;
         os << "  duplicate: " << duplicate << std::endl;
         return os.str();
      }
};

出力的にはこんな感じ

master_mind_cpp $ ./build/src/mastermind 6 4
Config:
  nColors: 6
  nPins: 4
  duplicate: 1

まとめ

argmentparseを追加しました. また, パラメータを管理するConfigクラスを作成しています.

コード

参考

他の記事