strict string to int[long]
Do we have a standard way of converting a char* to int (or long) in a strict way, i.e. we should get proper result only if all c开发者_如何学JAVAharacters are digits and can fit in an int (or long) -- some way by using strtol etc.. ?
Thus "sbc45", "4590k", " 56", "56 ", should be all invalid using that function.
This is a version close to what @GMan did, but it doesn't accept precedding spaces. e.g. " 101"
:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <exception>
long strict_conversion(const std::string& number_string)
{
long number;
std::stringstream convertor;
convertor << std::noskipws << number_string;
convertor >> number;
if( convertor.fail() || !convertor.eof() )
throw std::runtime_error("The string didn't pass the strict conversion!");
return number;
}
After one minute, here is the generic one:
template <typename NumberType>
NumberType strict_conversion(const std::string& number_string)
{
NumberType number;
std::stringstream convertor;
convertor << std::noskipws << number_string;
convertor >> number;
if( convertor.fail() || !convertor.eof() )
throw std::runtime_error("The string didn't pass the strict conversion!");
return number;
}
You can use strtol
- it returns the pointer to the first "error character" in input, so you can just check it for '\0'
to see if there is any garbage at end or not. If value is out of range, errno
is set to ERANGE
, so you can detect that, too.
The only caveat is that strtol
will quietly discard any leading whitespace. You can check for that yourself by applying isspace
to the first char of input.
I think I'd use something like this:
long convert(std::string const &s) {
if (s.find_first_not_of("0123456789") != std::string::npos)
throw std::invalid_argument("Cannot convert value");
return strtol(s.c_str(), NULL, 10);
}
精彩评论