Search code examples
c++boost

boost::program_options::options_description doesn't work for simplified command name


#include <boost/program_options.hpp>
namespace bpo = boost::program_options;

int main(int argc, char* argv[])
{
    int apple_num = 0, orange_num = 0;
    std::vector<std::string> addr;
    bpo::options_description opt("all options");

    opt.add_options()
        ("apple,a", bpo::value<int>(&apple_num)->default_value(10), "apple count")
        ("orange,o", bpo::value<int>(&orange_num)->default_value(20), "orange count")
        ("help", "apple+orange=");

    bpo::variables_map vm;

    try {
        bpo::store(parse_command_line(argc, argv, opt), vm);
    }
    catch (...) {
        std::cout << "error\n";
        return 0;
    }

    bpo::notify(vm);

    if (vm.count("help")) {
        std::cout << opt << std::endl;
        return 0;
    }

    std::cout << "apple count:" << apple_num << std::endl;
    std::cout << "orange count:" << orange_num << std::endl;
    std::cout << "sum:" << orange_num + apple_num << std::endl;
    return 0;
}

It works for a full command name as --apple or --orange

D:\test\ForTest\Debug> .\ForTest.exe --apple=100 --orange=99
apple count:100
orange count:99
sum:199

But it fails for --a or -a for a simplified --apple, I've already add both full and simplified command name "apple,a".

PS D:\test\ForTest\Debug> .\ForTest.exe -a=99
error
PS D:\test\ForTest\Debug>

Why?


Solution

  • The chosen commandline style doesn't expect the equals-sign with short options:

    ./sotest  -a=99
    error
    

    But

    ./sotest  -a 99
    apple count:99
    orange count:20
    sum:119
    

    To fix the expectations:

    auto style = bpo::command_line_style::default_style 
        | bpo::command_line_style::allow_long_disguise
        ;
    bpo::store(parse_command_line(argc, argv, opt, style), vm);
    

    Now you get

    Live On Coliru

    + ./sotest -a 7
    apple count:7
    orange count:20
    sum:27
    + ./sotest -a8
    apple count:8
    orange count:20
    sum:28
    + ./sotest -a=9
    apple count:9
    orange count:20
    sum:29
    + ./sotest --apple=100 --orange=31
    apple count:100
    orange count:31
    sum:131