boost::program_options 指定意外位置参数时不报告错误

boost::program_options reports no error when unexpected positional argument is specified

下面是一个使用 boost 解析选项的简单程序:

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

namespace po = boost::program_options;

int main(int argc, char **argv) 
{
    try
    {
        size_t param = std::numeric_limits<size_t>::max();

        po::options_description desc("Syntax: [options] \"input binary file\".\nAllowed options:");
        desc.add_options()
            ("help,h", "produce help message")
            ("param,p", po::value<size_t>(&param), "param");

        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
        po::notify(vm);

        if (vm.count("help")) 
        {
            std::cout << desc << "\n";
        }
        else
        {
            std::cout << "Running with param " << param << std::endl;
            return 0;
        }
    }
    catch(std::exception& e) {
        std::cerr << "error: " << e.what() << "\n";
    }
    catch(...) {
        std::cerr << "Exception of unknown type!\n";
    }
    return 1;
}

这里是生成的输出:

然而,这一切都是意料之中的: hex2txt.exe foo 输出 Running with param 0

我本以为会得到一个错误,因为 "foo" 不是预期的。我在这里做错了什么?

默认接受位置。您可以检查是否收到了 none,或者您可以指定您不允许任何:

po::positional_options_description positionals;
po::store(po::command_line_parser(args.size(), args.data())
                .options(desc)
                .positional(positionals)
                .run(),

演示

Live On Coliru

#include <boost/program_options.hpp>
#include <iostream>
#include <iomanip>

namespace po = boost::program_options;

int main() {
    std::vector<char const*> const cases[] = {
        { "hex2txt.exe" }, // outputs Running with param 0
        { "hex2txt.exe", "--param", "3" }, // outputs Running with param 3
        { "hex2txt.exe", "--toto" }, // outputs error: unrecognised option '--toto'
        // All this is expected, however:
        { "hex2txt.exe", "foo" }, // outputs Running with param 0
    };

    for (auto args : cases) {
        std::cout << "------";
        for (auto arg : args)
            std::cout << " " << std::quoted(arg);
        std::cout << "\n";

        try {
            size_t param = 0; // std::numeric_limits<size_t>::max();

            po::options_description desc(
                "Syntax: [options] \"input binary file\".\nAllowed options:");
            desc.add_options()("help,h", "produce help message")(
                "param,p", po::value<size_t>(&param), "param");

            po::positional_options_description positionals;

            po::variables_map vm;
            po::store(po::command_line_parser(args.size(), args.data())
                    .options(desc)
                    .positional(positionals)
                    .run(),
                vm);
            po::notify(vm);

            if (vm.count("help")) {
                std::cout << desc << "\n";
            } else {
                std::cout << "Running with param " << param << std::endl;
                //return 0;
            }
        } catch (std::exception const& e) {
            std::cerr << "error: " << e.what() << "\n";
        } catch (...) {
            std::cerr << "Exception of unknown type!\n";
        }
    }
}

版画

------ "hex2txt.exe"
Running with param 0
------ "hex2txt.exe" "--param" "3"
Running with param 3
------ "hex2txt.exe" "--toto"
error: unrecognised option '--toto'
------ "hex2txt.exe" "foo"
error: too many positional options have been specified on the command line