Suppose I have a program using boost::program_options to parse command line arguments, and one has an unsigned
value:
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
int main(int argc, char* argv[]) {
unsigned num;
po::options_description desc;
desc.add_options()
("num,n", po::value<unsigned>(&num), "Non-negative number");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
std::cout << "Number: " << num << '\n';
return 0;
}
Then if I pass a negative value on the command line, it accepts it and wraps it around:
$ ./bponeg -n -1 Number: 4294967295
I would rather that negative numbers trigger an error (i.e. throw invalid_option_value
) the same as it would if I wrote ./bponeg -n abc
.
From my own code after the parsing, it seems impossible to distinguish between the case where the user wrote -1
or if they wrote 4294967295
.
Can I instruct the program_options parser to reject negative inputs for unsigned
values?
You could write a custom validator, which would be something like:
struct nonnegative {
unsigned value;
};
void validate(boost::any& v, const std::vector<std::string>& values, nonnegative*, int)
{
using namespace boost::program_options;
validators::check_first_occurrence(v);
std::string const& s = validators::get_single_string(values);
if (s[0] == '-') {
throw validation_error(validation_error::invalid_option_value);
}
v = lexical_cast<unsigned>(s);
}
And then just use a nonnegative
instead of an unsigned
.
But I think it'd be easier to just use an int64_t
and throw an error if it's negative. Also less code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With