C++11 added some new string conversion functions:
http://en.cppreference.com/w/cpp/string/basic_string/stoul
It includes stoi (string to int), stol (string t
The most pat answer would be that the C library has no corresponding “strtou
”, and the C++11 string functions are all just thinly veiled wrappers around the C library functions: The std::sto*
functions mirror strto*
, and the std::to_string
functions use sprintf
.
Edit: As KennyTM points out, both stoi
and stol
use strtol
as the underlying conversion function, but it is still mysterious why while there exists stoul
that uses strtoul
, there is no corresponding stou
.
I've no idea why stoi
exists but not stou
, but the only difference between stoul
and a hypothetical stou
would be a check that the result is in the range of unsigned
:
unsigned stou(std::string const & str, size_t * idx = 0, int base = 10) {
unsigned long result = std::stoul(str, idx, base);
if (result > std::numeric_limits<unsigned>::max()) {
throw std::out_of_range("stou");
}
return result;
}
(Likewise, stoi
is also similar to stol
, just with a different range check; but since it already exists, there's no need to worry about exactly how to implement it.)
unsigned long ulval = std::stoul(buf);
unsigned long mask = ~0xffffffffl;
unsigned int uival;
if( (ulval & mask) == 0 )
uival = (unsigned int)ulval;
else {
...range error...
}
Using masks to do this with the expected value size in bits expressed in the mask, will make this work for 64-bit longs vs 32-bit ints, but also for 32-bit longs vs 32-bit ints.
In the case of 64-bit longs, ~0xffffffffl will become 0xffffffff00000000 and will thus see if any of the top 32 bits are set. With 32-bit longs, it ~0xffffffffl becomes 0x00000000 and the mask check will always be zero.