C++ 有哪些参数解析器库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/253556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:04:21  来源:igfitidea点击:

What parameter parser libraries are there for C++?

c++parsingoption

提问by Jim

I'd like to pass parameters to my C++ program in the following manner:

我想通过以下方式将参数传递给我的 C++ 程序:

./myprog --setting=value

Are there any libraries which will help me to do this easily?

是否有任何图书馆可以帮助我轻松做到这一点?

See also Argument-parsing helpers for C and Unix

另请参阅C 和 Unix 的参数解析助手

回答by Marcin Gil

GNU GetOpt.

GNU GetOpt

A simple example using 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;
}

You can also use optargif you have options that accept arguments.

如果您有接受参数的选项,您也可以使用optarg

回答by Remik Ziemlinski

I find it easier to use ezOptionParser. It's also a single header file, does not depend on anything but STL, works for Windows and Linux (very likely other platforms too), has no learning curve thanks to the examples, has features other libraries don't (like file import/export with comments, arbitrary option names with delimiters, auto usage formatting, etc), and is LGPL licensed.

我发现使用ezOptionParser更容易。它也是一个单一的头文件,除了 STL 不依赖任何东西,适用于 Windows 和 Linux(很可能也适用于其他平台),由于示例而没有学习曲线,具有其他库没有的功能(如文件导入/导出)带有注释、带有分隔符的任意选项名称、自动使用格式等),并且是 LGPL 许可的。

回答by cheshirekow

TCLAPis a really nice lightweight design and easy to use: http://tclap.sourceforge.net/

TCLAP是一个非常好的轻量级设计并且易于使用:http: //tclap.sourceforge.net/

回答by Max Lybbert

And there's a Google libraryavailable.

还有一个可用的谷歌图书馆

Really, command-line parsing is "solved." Just pick one.

真的,命令行解析已经“解决了”。随便选一个。

回答by Luca Davanzo

I think that GNU GetOpt is not too immediate to use.

我认为 GNU GetOpt 并不太容易使用。

Qt and Boost could be a solution, but you need to download and compile a lot of code.

Qt 和 Boost 可能是一个解决方案,但您需要下载和编译大量代码。

So I implemented a parser by myself that produces a std::map<std::string, std::string> of parameters.

所以我自己实现了一个解析器,它产生一个 std::map<std::string, std::string> 参数。

For example, calling:

例如,调用:

 ./myProgram -v -p 1234

map will be:

地图将是:

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

Usage is:

用法是:

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

主选项.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

主选项.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;
}

回答by Dusty Campbell

There are thesetools in the GNU C Library, which includes GetOpt.

GNU C 库中有这些工具,其中包括GetOpt

If you are using Qt and like the GetOpt interface, froglogichas published a nice interface here.

如果你使用 Qt 并且喜欢 GetOpt 接口,froglogic在这里发布了一个很好的接口。

回答by jamesdlin

Tooting my own horn if I may, I'd also like to suggest taking a look at an option parsing library that I've written: dropt.

如果可以的话,我会吹嘘自己的号角,我还想建议看看我写的一个选项解析库:dropt

  • It's a C library (with a C++ wrapper if desired).
  • It's lightweight.
  • It's extensible (custom argument types can be easily added and have equal footing with built-in argument types).
  • It should be very portable (it's written in standard C) with no dependencies (other than the C standard library).
  • It has a very unrestrictive license (zlib/libpng).
  • 它是一个 C 库(如果需要,可以使用 C++ 包装器)。
  • 它很轻。
  • 它是可扩展的(可以轻松添加自定义参数类型并与内置参数类型具有同等地位)。
  • 它应该是非常可移植的(它是用标准 C 编写的),没有依赖项(除了 C 标准库)。
  • 它有一个非常不受限制的许可证 (zlib/libpng)。

One feature that it offers that many others don't is the ability to override earlier options. For example, if you have a shell alias:

它提供的许多其他功能没有的一项功能是能够覆盖早期的选项。例如,如果您有一个 shell 别名:

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

and you want to use barbut with--flag1disabled, it allows you to do:

并且您想使用bar--flag1禁用时,它允许您执行以下操作:

bar --flag1=0

回答by maxschlepzig

Qt 5.2 comes with a command line parser API.

Qt 5.2 带有一个命令行解析器 API

Small example:

小例子:

#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;
}

Example output

示例输出

The automatically generated help screen:

自动生成的帮助屏幕:

$ ./qtopt -h
Usage: ./qtopt [options] infile
Tool for doing X.

Options:
  -h, --help               Displays this help.
  -v, --version            Displays version information.
  -+                       be verbose
  -o, --output   Output file.

Arguments:
  infile                   Input file.

Automatically generated version output:

自动生成的版本输出:

$ ./qtopt -v
ToolX 1.2

Some real calls:

一些真实的电话:

$ ./qtopt b1 -+ -o tmp blah.foo
Input files:  ("b1", "blah.foo") , verbose:  true , output:  "tmp"
$ ./qtopt          
Input files:  () , verbose:  false , output:  "out"

A parse error:

解析错误:

$ ./qtopt --hlp
Unknown option 'hlp'.
$ echo $?
1

Conclusion

结论

If your program already use the Qt (>= 5.2) libraries, its command line parsing API is convenient enough to get the job done.

如果您的程序已经使用 Qt (>= 5.2) 库,则其命令行解析 API 足以方便地完成工作。

Be aware that builtin Qt options are consumed by QApplicationbefore the option parser runs.

请注意,内置 Qt 选项QApplication在选项解析器运行之前被消耗。

回答by Luc Hermitte

argstreamis quite similar to boost.program_option: it permits to bind variables to options, etc. However it does not handle options stored in a configuration file.

argstream非常类似于boost.program_option:它允许将变量绑定到选项等。但是它不处理存储在配置文件中的选项。