【问题标题】:boost program_options custom parsingboost program_options 自定义解析
【发布时间】:2016-09-27 10:21:36
【问题描述】:

有什么办法可以得到类似的东西

myapp hostname:port

由 boost program_options 解析?我也在使用其他选项,我很想使用 boost program_options 而不必为 argc/argv 滚动我自己的解析器。

我尝试了一些组合

desc.add_options()
    ("help", "list all available options")
    (new MyCustomValue(&store_var), "")

但是没用

【问题讨论】:

  • 自定义验证器的documentation 应该对此有所了解。
  • @DanMašek 这不是一个简单的原因:它还需要为完整或缩短的选项加上前缀,例如myapp -a hostname:port 虽然我只想输入类似 ssh:myapp hostname:port 之前没有 -something 的内容。
  • Positional options 会这样做。
  • 完美!请给出答案,我会接受的。

标签: c++ templates boost command-line boost-program-options


【解决方案1】:

正如 Dan Mašek 所写,这看起来更适合位置论证。但是,由于您为选项指定了特定结构,因此您可能需要添加 std::regex_match

假设你开始

#include <string>
#include <iostream>
#include <regex>
#include <boost/program_options.hpp>

using namespace std;
using namespace boost::program_options;

int main(int argc, const char *argv[]) {
    try {
        options_description desc{"Options"};
        desc.add_options()
            ("help,h", "Help screen")
            ("ip_port", value<std::string>()->required(), "ip:port");

        positional_options_description pos_desc;
        pos_desc.add("ip_port", -1);

        command_line_parser parser{argc, argv};
        parser.options(desc).positional(pos_desc).allow_unregistered();
        parsed_options parsed_options = parser.run();

        variables_map vm;
        store(parsed_options, vm);
        notify(vm);

        const auto ip_port = vm["ip_port"].as<string>();

此时,我们得到了ip_port 的用户输入。我们可以定义一个正则表达式来匹配它。请注意,第一部分可以是字符串(例如,localhost),但第二部分必须是整数:

        const regex ip_port_re("([^:]+):([[:digit:]]+)");
        smatch ip_port_match;
        if(!regex_match(ip_port, ip_port_match, ip_port_re)) 
             throw validation_error{validation_error::invalid_option_value, ip_port, "ip_port"};
        cout << "ip: " << ip_port_match[1] << " port: " << ip_port_match[2] << endl;
    }
    catch (const error &ex) {
        cerr << ex.what() << '\n';
    }
}

运行时是这样的:

$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out 127.0.0.1:30
ip: 127.0.0.1 port: 30
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out localhost:30
ip: localhost port: 30
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out localhost:30d
the argument for option 'localhost:30d' is invalid
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out 
the option '--ip_port' is required but missing
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out localhost:30 foo
option '--ip_port' cannot be specified more than once

【讨论】:

    猜你喜欢
    • 2023-01-11
    • 2019-01-15
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    相关资源
    最近更新 更多