Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to convert string to unsigned number in C++

Tags:

c++

I tried to use:

std::string s = "-150";
unsigned int a = atoi(s.c_str());
std::cout << a;

and

std::string s = "-150";
std::istringstream reader(s);
unsigned int a;
reader >> a;
std::cout << a;

I always get 4294967146. I understand that it's a U_INT_MAX - 150.
How can I get an error if number can't be converted, cause input data was invalid? Or (at least) auto-convert to 150.
P.S.
I want to find a way without my manipulation on string.

like image 893
sashaaero Avatar asked Jan 02 '26 03:01

sashaaero


1 Answers

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).

like image 144
Toby Speight Avatar answered Jan 03 '26 16:01

Toby Speight



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!