It seems that even std::stoul doesn't reject negative numbers (presumably due to the requirements of strtoul, which it uses). Here's a test program to demonstrate:
#include <iostream> // std::cout, etc. #include <string> // std::string, std::stoul #include <stdexcept> // std::invalid_argument, std::out_of_range #include <limits> // std::numeric_limits int main(int, char **argv) { while (*++argv) { std::string str(*argv); try { unsigned long u = std::stoul(str); if (u > std::numeric_limits<unsigned int>::max()) throw std::out_of_range(str); unsigned int i = u; std::cout << "Value = " << i << std::endl; } catch (const std::invalid_argument& e) { std::cout << "Input could not be parsed: " << e.what() << std::endl; } catch (const std::out_of_range& e) { std::cout << "Input out of range: " << e.what() << std::endl; } } }
Running this with arguments 150 -150 abc gives
Value = 150 Input out of range: -150 Input could not be parsed: stoul
But, if we remove the std::numeric_limits test, we get
Value = 150 Value = 4294967146 Input could not be parsed: stoul
TL;DR
Read as an unsigned long and test the range yourself (wrap it up in a function - perhaps even a template function - if you find you need it in many places).
abs()function, I think that's what you're looking for actually.atoiis concerned.std::stoifamily of functions it will raise an exception if there is an invalid conversion.