使用boost::program_options打印常规参数和位置参数的帮助信息

21

如果您使用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一样,还是必须手动操作?显然,<<不能用于positional_options_description,编译错误如下:

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

4
如果有帮助的话,您可以在这里找到完整的代码 [http://www.boost.org/libs/program_options/example/options_description.cpp]。 - user1252091
1
谢谢llonesmiz,确实帮了很多忙!我以为如果我把位置参数添加到“options_description”中,就不必再添加到“positional_options_description”中,但是实际上需要两者都添加。 - nuoritoveri
3个回答

6
请注意,流式描述只打印选项,不会打印程序名称或实际描述程序的内容。您应该手动将任何位置参数作为输出消息的一部分打印出来。
改为:
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中。这就是为什么它没有被打印出来。通常情况下会打印出来,所以你的代码做到了我想要的,只是我在其他地方犯了错误。我也同意在开头打印用法信息很好。 - nuoritoveri

2

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

错误信息与此无关,我忘记具体是关于cpp11的什么东西了。


2

以下是我自动打印位置选项的方法:

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),才需要检查重复参数名称的逻辑;否则,您可以简化此过程,例如用os << " " << n;替换if... else if ...

使用当前(1.68)版本的boost,无法确定选项说明是否为位置描述,因此没有什么可以改进帮助文档,例如排除打印位置选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接