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

Print help for both normal and positional args with boost::program_options

本文关键字:参数 位置 帮助 打印 program boost options 使用      更新时间:2023-10-16

当你使用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>&&’

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

不是

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;
}

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

错误信息是无关的,我忘记了cpp11

我是这样自动打印位置选项的:

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;
}

检查重复参数名称的逻辑只需要当你有重复的选项,可以重复无限次,即count等于-1,否则你可以简化一点,例如将if... else if ...替换为os << " " << n;

在当前(1.68)版本的boost中,没有办法告诉选项描述是否是位置的,所以没有办法改进帮助,例如,从打印中排除位置选项。