19

当您使用 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

3 回答 3

5

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

代替

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;
}
于 2013-01-02T19:03:46.920 回答
2

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

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

于 2013-01-02T19:06:29.237 回答
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;
}

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

使用当前 (1.68) 版本的 boost,无法判断选项描述是否是位置的,因此无需做任何事情来改进帮助,例如,不打印位置选项。

于 2018-11-28T08:39:27.223 回答