web-dev-qa-db-ja.com

C ++にはどのようなパラメーターパーサーライブラリがありますか?

次の方法でC++プログラムにパラメーターを渡します。

./myprog --setting=value

これを簡単に行うのに役立つライブラリはありますか?

CおよびUnixの引数解析ヘルパー も参照してください。

67
Jim
37
Igor Semenov

GNU GetOpt

GetOptを使用した簡単な例:

// C/C++ Libraries:
#include <string>
#include <iostream>
#include <unistd.h>

// Namespaces:
using namespace std;

int main(int argc, char** argv) {
    int opt;
    bool flagA = false;
    bool flagB = false;

    // Shut GetOpt error messages down (return '?'): 
    opterr = 0;

    // Retrieve the options:
    while ( (opt = getopt(argc, argv, "ab")) != -1 ) {  // for each option...
        switch ( opt ) {
            case 'a':
                    flagA = true;
                break;
            case 'b':
                    flagB = true;
                break;
            case '?':  // unknown option...
                    cerr << "Unknown option: '" << char(optopt) << "'!" << endl;
                break;
        }
    }

    // Debug:
    cout << "flagA = " << flagA << endl;
    cout << "flagB = " << flagB << endl;

    return 0;
}

引数を受け入れるオプションがある場合は、 optarg を使用することもできます。

22
Marcin Gil

TCLAP は本当にすてきな軽量設計で使いやすいです。 http://tclap.sourceforge.net/

19
cheshirekow

ezOptionParser を使用する方が簡単です。また、単一のヘッダーファイルであり、STL以外に依存せず、WindowsおよびLinux(他のプラットフォームでも可能性が高い)で動作し、例のおかげで学習曲線がなく、他のライブラリにはない機能(ファイルのインポート/エクスポートなど)コメント、デリミタ付きの任意のオプション名、自動使用フォーマットなど)を含み、LGPLライセンスです。

17

Googleライブラリ が利用可能です。

本当に、コマンドライン解析は「解決されます」。 1つだけ選択してください。

14
Max Lybbert

GNU Cライブラリには これら ツールがあり、これには GetOpt が含まれます。

Qtを使用しており、GetOptインターフェイスが好きな場合、 froglogic はNiceインターフェイス here を公開しています。

8
Dusty Campbell

GNU GetOptはすぐには使用できないと思います。

QtとBoostがソリューションになる可能性がありますが、多くのコードをダウンロードしてコンパイルする必要があります。

そこで、自分でパラメーターのstd :: map <std :: string、std :: string>を生成するパーサーを実装しました。

たとえば、次の呼び出し:

 ./myProgram -v -p 1234

マップは次のようになります。

 ["-v"][""]
 ["-p"]["1234"]

使用法は次のとおりです。

int main(int argc, char *argv[]) {
    MainOptions mo(argc, argv);
    MainOptions::Option* opt = mo.getParamFromKey("-p");
    const string type = opt ? (*opt).second : "";
    cout << type << endl; /* Prints 1234 */
    /* Your check code */
}

MainOptions.h

#ifndef MAINOPTIONS_H_
#define MAINOPTIONS_H_

#include <map>
#include <string>

class MainOptions {
public:
    typedef std::pair<std::string, std::string> Option;
    MainOptions(int argc, char *argv[]);
    virtual ~MainOptions();
    std::string getAppName() const;
    bool hasKey(const std::string&) const;
    Option* getParamFromKey(const std::string&) const;
    void printOptions() const;
private:
    typedef std::map<std::string, std::string> Options;
    void parse();
    const char* const *begin() const;
    const char* const *end() const;
    const char* const *last() const;
    Options options_;
    int argc_;
    char** argv_;
    std::string appName_;
};

MainOptions.cpp

#include "MainOptions.h"

#include <iostream>

using namespace std;

MainOptions::MainOptions(int argc, char* argv[]) :
        argc_(argc),
        argv_(argv) {
    appName_ = argv_[0];
    this->parse();
}

MainOptions::~MainOptions() {
}

std::string MainOptions::getAppName() const {
    return appName_;
}

void MainOptions::parse() {
    typedef pair<string, string> Option;
    Option* option = new pair<string, string>();
    for (const char* const * i = this->begin() + 1; i != this->end(); i++) {
        const string p = *i;
        if (option->first == "" && p[0] == '-') {
            option->first = p;
            if (i == this->last()) {
                options_.insert(Option(option->first, option->second));
            }
            continue;
        } else if (option->first != "" && p[0] == '-') {
            option->second = "null"; /* or leave empty? */
            options_.insert(Option(option->first, option->second));
            option->first = p;
            option->second = "";
            if (i == this->last()) {
                options_.insert(Option(option->first, option->second));
            }
            continue;
        } else if (option->first != "") {
            option->second = p;
            options_.insert(Option(option->first, option->second));
            option->first = "";
            option->second = "";
            continue;
        }
    }
}

void MainOptions::printOptions() const {
    std::map<std::string, std::string>::const_iterator m = options_.begin();
    int i = 0;
    if (options_.empty()) {
        cout << "No parameters\n";
    }
    for (; m != options_.end(); m++, ++i) {
        cout << "Parameter [" << i << "] [" << (*m).first << " " << (*m).second
                << "]\n";
    }
}

const char* const *MainOptions::begin() const {
    return argv_;
}

const char* const *MainOptions::end() const {
    return argv_ + argc_;
}

const char* const *MainOptions::last() const {
    return argv_ + argc_ - 1;
}

bool MainOptions::hasKey(const std::string& key) const {
    return options_.find(key) != options_.end();
}

MainOptions::Option* MainOptions::getParamFromKey(
        const std::string& key) const {
    const Options::const_iterator i = options_.find(key);
    MainOptions::Option* o = 0;
    if (i != options_.end()) {
        o = new MainOptions::Option((*i).first, (*i).second);
    }
    return o;
}
7
Luca Davanzo

必要に応じて自分のホーンを鳴らして、私が書いたオプション解析ライブラリ dropt を見てみることもお勧めします。

  • Cライブラリです(必要に応じてC++ラッパーを使用)。
  • 軽量です。
  • 拡張可能です(カスタム引数タイプは簡単に追加でき、組み込みの引数タイプと同等の基盤を持ちます)。
  • 依存性のない(C標準ライブラリ以外)、非常に移植性が高い(標準Cで記述されている)必要があります。
  • 非常に制限のないライセンス(zlib/libpng)があります。

他の多くのユーザーが提供していない機能の1つは、以前のオプションをオーバーライドする機能です。たとえば、シェルエイリアスがある場合:

alias bar="foo --flag1 --flag2 --flag3"

barを使用しますが、with--flag1無効、次のことができます。

bar --flag1=0
6
jamesdlin

CLPPライブラリを試してください。コマンドラインパラメーターの解析のためのシンプルで柔軟なライブラリです。ヘッダーのみでクロスプラットフォーム。 ISO C++およびBoost C++ライブラリのみを使用します。私見では、Boost.Program_optionsより簡単です。

ライブラリ: http://sourceforge.net/projects/clp-parser/

2010年10月26日-新しいリリース2.0rc。多くのバグが修正され、ソースコード、ドキュメント、例、コメントの完全なリファクタリングが修正されました。

3

Qt 5.2には コマンドラインパーサーAPI が付属しています。

小さな例:

#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>

int main(int argc, char **argv)
{
  QCoreApplication app(argc, argv);
  app.setApplicationName("ToolX");
  app.setApplicationVersion("1.2");

  QCommandLineParser parser;
  parser.setApplicationDescription("Tool for doing X.");
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addPositionalArgument("infile",
      QCoreApplication::translate("main", "Input file."));

  QCommandLineOption verbose_opt("+",
      QCoreApplication::translate("main", "be verbose"));
  parser.addOption(verbose_opt);

  QCommandLineOption out_opt(QStringList() << "o" << "output",
      QCoreApplication::translate("main", "Output file."),
      QCoreApplication::translate("main", "filename"), // value name
      QCoreApplication::translate("main", "out")   // default value
      );
  parser.addOption(out_opt);

  // exits on error
  parser.process(app);

  const QStringList args = parser.positionalArguments();

  qDebug() << "Input files: " << args
    << ", verbose: " << parser.isSet(verbose_opt)
    << ", output: " << parser.value(out_opt)
    << '\n';
  return 0;
}

出力例

自動生成されたヘルプ画面:

 $ ./qtopt -h 
使用法:./qtopt [オプション] infile 
 Xを実行するためのツール。
 
オプション:
 -h、--helpこのヘルプを表示します。
 -v、--versionバージョン情報を表示します。
-+ be verbose 
 -o、--output出力ファイル。 
 
引数:
 infile入力ファイル。

自動生成されたバージョン出力:

 $ ./qtopt -v 
 ToolX 1.2 

いくつかの実際の呼び出し:

 $ ./qtopt b1-+ -o tmp blah.foo 
入力ファイル:( "b1"、 "blah.foo")、冗長:true、出力: "tmp" 
 $ ./qtopt 
入力ファイル:()、冗長:false、出力: "out" 

解析エラー:

 $ ./qtopt --hlp 
不明なオプション 'hlp'。
 $ echo $?
 1 

結論

プログラムがすでにQt(> = 5.2)ライブラリを使用している場合、そのコマンドライン解析APIは仕事を完了するのに十分便利です。

オプションパーサーが実行される前に、組み込みのQtオプションがQApplicationによって消費されることに注意してください。

3
maxschlepzig

argstreamboost.program_optionと非常に似ています:変数をオプションなどにバインドできます。ただし、構成ファイルに保存されているオプションは処理しません。

3
Luc Hermitte

私の小さなoptionsヘッダー(166 locなので簡単にハッキング可能) options.hpp を試すことができます。それは単一のヘッダー実装であり、あなたが求めることをする必要があります。また、ヘルプページが自動的に印刷されます。

1
burner