boost program options short / long parameter names

£可爱£侵袭症+ 提交于 2021-01-29 04:58:12

问题


I have implemented a routing to print out all of the options that are available in my boost::program_options objects along with their current values by iterating over the po::variable_map.

With this I can directly print the long name of the option along with its value. However, I do not know, how to retrieve the short option name from the long option name (i.e. -h from --help). Any suggestions how to do this?


回答1:


I remember describing in a recent answer why variable_map is "too late" to know about the option descriptions:

  • Boost. Handy variables_map. Taking advantage of having specified the type in the options_desctription

In short, the variable_map sits in the Storage Component of the library and as such is isolated from the Option Descriptions (which lives in the Options Description Component).

What can you do?

You could work with the intermediate results, the raw output from the Parsers Component:

The results of parsing are returned as an instance of the parsed_options class. Typically, that object is passed directly to the storage component. However, it also can be used directly, or undergo some additional processing

So, let's try to work out a sample here:

    po::parsed_options const intermediate = po::parse_command_line(ac, av, desc);

    //////////////////////////////////
    // print the extended usage info as per the question
    //
    for (auto& entry : intermediate.options)
    {
        po::option_description const& opt = desc.find(entry.string_key, false, false, false); 

        std::cout << "\nActual tokens involved: ";
        for (auto& tok : entry.original_tokens)
            std::cout << "'" << tok << "' ";
        for (std::string const& v : entry.value)
            std::cout << "\nAssociated value: " << v;
        std::cout << "\n-----------------------------------------------------------\n";
        std::cout << "opt.format_name()        : "        << opt.format_name()                                      << "\n";
        std::cout << "opt.long_name()          : "        << opt.long_name()                                        << "\n";
        std::cout << "opt.canonical_display_name('-'): "  << opt.canonical_display_name(cls::allow_dash_for_short)  << "\n";
        std::cout << "opt.canonical_display_name('/'): "  << opt.canonical_display_name(cls::allow_slash_for_short) << "\n";
        std::cout << "opt.canonical_display_name('--'): " << opt.canonical_display_name(cls::allow_long)            << "\n";
    }

Note: with the lookup by key, you can practically also use the variable_map after all.

Prints e.g.

Actual tokens involved: '-C' '42' 
Associated value: 42
-----------------------------------------------------------
opt.format_name()        : -C [ --compression ]
opt.long_name()          : compression
opt.canonical_display_name('-'): -C
opt.canonical_display_name('/'): /C
opt.canonical_display_name('--'): --compression

Actual tokens involved: '--name' 'santa' 
Associated value: santa
-----------------------------------------------------------
opt.format_name()        : -n [ --name ]
opt.long_name()          : name
opt.canonical_display_name('-'): -n
opt.canonical_display_name('/'): /n
opt.canonical_display_name('--'): --name
Compression level was set to 42.

Live On Coliru

#include <boost/program_options.hpp>
#include <boost/program_options/detail/parsers.hpp>
#include <iostream>

namespace po  = boost::program_options;
namespace cls = po::command_line_style;

int main(int ac, char** av) {
    // Declare the supported options.
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("name,n", po::value<std::string>(), "specify the name")
        ("compression,C", po::value<int>(), "set compression level")
        ;

    po::variables_map vm;
    po::parsed_options const intermediate = po::parse_command_line(ac, av, desc);

    //////////////////////////////////
    // print the extended usage info as per the question
    //
    for (auto& entry : intermediate.options)
    {
        po::option_description const& opt = desc.find(entry.string_key, false, false, false); 

        std::cout << "\nActual tokens involved: ";
        for (auto& tok : entry.original_tokens)
            std::cout << "'" << tok << "' ";
        for (std::string const& v : entry.value)
            std::cout << "\nAssociated value: " << v;
        std::cout << "\n-----------------------------------------------------------\n";
        std::cout << "opt.format_name()        : "        << opt.format_name()                                      << "\n";
        std::cout << "opt.long_name()          : "        << opt.long_name()                                        << "\n";
        std::cout << "opt.canonical_display_name('-'): "  << opt.canonical_display_name(cls::allow_dash_for_short)  << "\n";
        std::cout << "opt.canonical_display_name('/'): "  << opt.canonical_display_name(cls::allow_slash_for_short) << "\n";
        std::cout << "opt.canonical_display_name('--'): " << opt.canonical_display_name(cls::allow_long)            << "\n";
    }

    //////////////////////////////////

    po::store(intermediate, vm);
    po::notify(vm);    

    if (vm.count("help")) {
        std::cout << desc << "\n";
        return 1;
    }

    if (vm.count("compression")) {
        std::cout << "Compression level was set to " 
            << vm["compression"].as<int>() << ".\n";
    } else {
        std::cout << "Compression level was not set.\n";
    }
}


来源:https://stackoverflow.com/questions/32254979/boost-program-options-short-long-parameter-names

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!