【问题标题】:Print help for both normal and positional args with boost::program_options使用 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,但您必须同时添加它们。

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


【解决方案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 中,无法判断选项描述是否是位置性的,因此无需改进帮助,例如排除打印位置性选项。

    【讨论】:

      猜你喜欢
      • 2017-05-31
      • 2011-12-29
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多