2016-04-22 74 views
4

假设我有一个程序使用boost :: program_options解析命令行参数,以及一个具有unsigned值:如果我通过负不允许用升压:: program_options无符号值负参数

#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; 
} 

然后在命令行上的值,它接受它,并围绕其包装:

$ ./bponeg -n -1 
Number: 4294967295

我宁愿是负数触发错误(即扔invalid_option_value)一样,它想如果我写./bponeg -n abc。 从解析后的我自己的代码中,似乎不可能区分用户写入-1或写入4294967295的情况。

我可以指示program_options解析器拒绝unsigned值的负输入吗?

+4

只需阅读已签名的值并检查它是否为负值。我不是使用无符号类型进行任何事情的朋友,但无论如何都有点烦人。 (Ib4通常很讨厌:标准委员会的几位成员同意我的看法,例如参见[本小组](https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything)9 :50,42:40,1:02:50) –

+3

@BaummitAugen无符号值超出签名范围的情况如何? –

+2

@Revolver_Ocelot如果你需要额外的位,并且使用下一个更大的有符号整数不是一个选项,那么你必须做你必须做的。尽管如此,从来没有发生过我。 vOv –

回答

7

可以写一个custom validator,这将是这样的:

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); 
} 

,然后只用一个nonnegative代替unsigned的。

但我觉得这是比较容易,只需使用一个int64_t,并抛出一个错误,如果它是消极的。代码也少一些。