-1

I have a string like below:

std::string strl="ffffffffffffffffffffffffffffffffffffffffffff";

I want to convert it into uint32_t variable like below:

uint32_t val = std::stoul(strl, nullptr, 16);

The above operation gives a "SIGABRT" signal and gives error:

terminate called after throwing an instance of 'std::out_of_range'
what():  stoul.

What changes to be done for resolving the issue or it is not possible with uint32_t datatype to store the string.

Santosh Sahu
  • 2,134
  • 6
  • 27
  • 51
  • There are four bits per hex digit. How many bits does your string specify? – Cheers and hth. - Alf Mar 02 '18 at 12:15
  • `std::string strl="0xffffffff";` is all you can fit in `uint32_t` and by the way that's a terrible variable name (too close to `stol` etc.) – Justin Randall Mar 02 '18 at 12:15
  • 1
    How many bits is in an `uint32_t`? How many hexadecimal digits are needed for those bits? How many hexadecimal digits do you present to `std::stoul`? – Some programmer dude Mar 02 '18 at 12:15
  • 1
    Also note that the `l` in `stoul` stands for `long`. The exact bit-width of `long` is not specified except that it must be at least 32 bits, and no bigger than `long long`. So a `long` might be bigger than the 32 bits of `uint32_t`. – Some programmer dude Mar 02 '18 at 12:19

2 Answers2

2

uint32_t can only store up to 0xffffffff as it's a 32 bit unsigned type, so it's not possible to store your string with that data type.

For the string you present, you'll need a big integer library to parse it.

Boost has a good one, and even includes typedefs like uint1024_t, so it's very simple to use.

See http://www.boost.org/doc/libs/1_58_0/libs/multiprecision/doc/html/index.html

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

If you really want to store the number in a uint32_t, you'll need to validate it.

I would approach it something like this:

#include <string>
#include <cstdint>
#include <stdexcept>
#include <iostream>

auto parse_hex_uint32(std::string const& input) -> std::uint32_t
try
{
    std::size_t read_len = 0;

    auto initial_result = std::stoull(input, &read_len, 16);
    if (read_len != input.size())
    {
        throw std::runtime_error("invalid input: " + input);
    }
    if (initial_result > std::numeric_limits<std::uint32_t>::max())
    {
        throw std::out_of_range("number too large: " + std::to_string(initial_result));
    }

    return std::uint32_t(initial_result);
}
catch(...)
{
    std::throw_with_nested(std::runtime_error("failed to parse " + input + " as hex uint32"));
}

void print_exception(const std::exception& e, int level =  0)
{
    std::cerr << std::string(level, ' ') << "exception: " << e.what() << '\n';
    try {
        std::rethrow_if_nested(e);
    } catch(const std::exception& e) {
        print_exception(e, level+1);
    } catch(...) {}
}

int main()
{
    using namespace std::literals;
    auto input = "ffffffffffffffff"s;
    try
    {
        std::cout << parse_hex_uint32(input) << std::endl;
        return 0;
    }
    catch(std::exception& e)
    {
        print_exception(e);
        return 100;
    }
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142