当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《C++有哪些参数解析器库?》经验,为你挑选了8个好方法。

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

./myprog --setting=value

是否有任何图书馆可以帮助我轻松完成这项工作?

另请参阅C和Unix的Argument-parsing helpers



1> 小智..:

Boost.Program_options


这似乎是C++最明显的选择,但其文档不够完整.尝试找到如何存储和检索文件中的选项,这是一项基本功能.我不喜欢使用它的代码看起来如何,特别是措辞`options.add_options()(option1)(option2)...`我认为这是滥用C++语法.
使用Boost.Program_options编译代码似乎并不简单,除了包含头文件之外,还需要链接选项等等.
你可以得到更多相同的东西.如果你想要`--long-option`之类的东西,那么自己做起来相当简单.

2> Marcin Gil..:

GNU GetOpt.

使用GetOpt的一个简单示例:

// C/C++ Libraries:
#include 
#include 
#include 

// 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.


Ughh.我理解在C代码中使用这个库,但IMO,这在我编写的任何C++应用程序中都是不可接受的.如果您不需要纯C.,找一个更好的库.

3> cheshirekow..:

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


我使用过getopt,google的gflags,来自Boost的program_options和tclap是非常棒的*.我不能说tclap足够好的东西,特别是考虑到可用的替代方案.我所拥有的抱怨的程度是,它有助于格式化与我的眼睛习惯的"不同".

4> 小智..:

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


我刚尝试了exOptionParser,但它有很多问题.首先,我得到58个关于unsigned int到int转换的警告.它还尝试增加列表迭代器(不能像这样使用)和崩溃.它的界面也很糟糕.它使用遍布各处的引用,而不仅仅返回您想要的数据.它看起来像一个C库,即使它是建立在C++ STL之上的.

5> Max Lybbert..:

并且有一个Google库可用.

实际上,命令行解析是"已解决".选择一个.



6> Dusty Campbe..:

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

如果您正在使用Qt并且喜欢GetOpt界面,那么froglogic已经在这里发布了一个很好的界面.



7> Luca Davanzo..:

我认为GNU GetOpt不是太直接使用.

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

所以我自己实现了一个解析器,它生成了参数的std :: map .

例如,调用:

 ./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 
#include 

class MainOptions {
public:
    typedef std::pair 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 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 

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 Option;
    Option* option = new pair();
    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::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;
}



8> jamesdlin..:

如果可能的话,嘟嘟我自己的号角,我还想建议看一下我写过的解析库的选项:dropt.

它是一个C库(如果需要,可以使用C++包装器).

它很轻巧.

它是可扩展的(自定义参数类型可以轻松添加,并与内置参数类型具有相同的基础).

它应该是非常可移植的(它是用标准C编写的),没有依赖性(除了C标准库).

它有一个非常不受限制的许可证(zlib/libpng).

它提供的许多其他功能不具备覆盖早期选项的功能.例如,如果您有一个shell别名:

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

并且你想使用bar但有--flag1残疾,它允许你做:

bar --flag1=0

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有