使用 boost::program_options 打印普通和位置参数的帮助

Posted

技术标签:

【中文标题】使用 boost::program_options 打印普通和位置参数的帮助【英文标题】:Print help for both normal and positional args with boost::program_options 【发布时间】:2012-12-17 01:54:12 【问题描述】:

当您使用 Boost 库 program_options 时,很容易为您的程序打印帮助:

boost::program_options::variables_map options;
boost::program_options::options_description optionsDesc;
boost::program_options::positional_options_description positionalOptionsDesc;
//...
if(options.count("help"))

    cerr << optionsDesc << endl;

但是如何将positional_options_description 中的选项添加到帮助消息中?在本教程中,我可以在本节末尾看到这种设置的输出:

http://www.boost.org/doc/libs/1_52_0/doc/html/program_options/tutorial.html#id2607297

选项input-file 打印在帮助中,它是定位的。但我看不到代码。 有没有内置的打印方式,比如options_description,或者你必须手动打印?显然&lt;&lt;不适用于positional_options_description,编译错误是:

error: cannot bind ‘std::ostream aka std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’

【问题讨论】:

如果有帮助,可以找到完整代码here。 感谢 llonesmiz,确实帮了大忙!我认为如果我将它们添加到positional_options_description,我不必将位置参数添加到options_description,但您必须同时添加它们。 【参考方案1】:

请注意,流式描述仅打印出选项。它不会打印程序的名称或程序功能的实际描述。您应该手动打印作为输出消息一部分的任何位置参数:

代替

if (vm.count("help")) 
    cout << "Usage: options_description [options]\n";
    cout << desc;
    return 0;

你可以很容易地说

if (vm.count("help")) 
    cout << "Usage: " << argv[0] << " [options] <description of positional 1> <description of positional 2> ...\n";
    cout << desc;
    return 0;

【讨论】:

正如我在对问题的评论中所说,我没有将位置参数添加到options_description,只是添加到positional_options_description。这就是为什么它没有被打印出来。它通常是这样,所以你的代码做我想要的,我只是在另一个地方犯了错误。我也同意一开始就打印用法很好。【参考方案2】:

看看 boost::program_options::positional_options_description.name_for_position(i)

错误消息是无关的,我忘记了与 cpp11 有什么关系

【讨论】:

【参考方案3】:

这是我为自动打印位置选项所做的:

void printUsage(const std::string &argv0)

    std::ostream &os = std::cout;

    os << "Usage:" << std::endl;

    // print only basename of argv[0]
    boost::filesystem::path p(argv0);
    os << "  " << p.filename().string();

    os << " [options]";

    std::string last = "";
    int rep = 0;
    for(int i = 0; i < positional_options_description_.max_total_count(); i++)
    
        const std::string &n = positional_options_description_.name_for_position(i);
        if(n == last)
        
            if(!rep) os << " ...";
            if(rep++ > 1000) break;
        
        else
        
            os << " " << n;
            last = n;
            rep = 0;
        
    
    os << std::endl << std::endl;
    os << options_description_ << std::endl;

仅当您有可以重复无限次的重复选项(即计数等于-1)时才需要检查重复参数名称的逻辑,否则您可以稍微简化一下,例如将if... else if ... 替换为os &lt;&lt; " " &lt;&lt; n;

在当前 (1.68) 版本的 boost 中,无法判断选项描述是否是位置性的,因此无需改进帮助,例如排除打印位置性选项。

【讨论】:

以上是关于使用 boost::program_options 打印普通和位置参数的帮助的主要内容,如果未能解决你的问题,请参考以下文章

c++/boost program_options 一个选项禁用其他

Boost.Program_Options:当 <bool> 被指定为命令行选项时,啥是有效的命令行参数?

未定义的引用`boost :: program_options :: options_description :: m_default_line_length'

Boost 链接问题 - 多个版本

如何将boost :: any打印到流中?

用序列容器解析命令行选项?