4

I have a std::string representing a 64-bit memory address in little-endian, hexadecimal form. How to convert this to a uint64_t representation?

RouteMapper
  • 2,484
  • 1
  • 26
  • 45
  • possible duplicate of [How do you get an unsigned long out of a string?](http://stackoverflow.com/questions/1484140/how-do-you-get-an-unsigned-long-out-of-a-string) – Brian Cain Jul 15 '13 at 19:09
  • see also http://stackoverflow.com/questions/5117844/c-string-streams – Brian Cain Jul 15 '13 at 19:09
  • What exactly do you mean by "little-endian, hexadecimal"? In 16 bits, would the number `0x1234` be represented by the string `"4321"` or `"3412"` (i.e., is it byte-wise or hex-digit-wise little-endian)? – Keith Thompson Jul 15 '13 at 20:14

1 Answers1

5
#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>
#include <cstdint>

int main()
{
    std::string s("0x12345");
    std::stringstream strm(s);
    std::uint64_t n;
    strm >> std::hex >> n;
    std::cout << std::hex << n << std::endl;
    return 0;
}

This prints 12345, as expected.

Edit: If you want to convert from little-endian to big-endian, that's possible too:

#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstdint>

int main()
{
    std::string s("0x12345");
    std::stringstream strm(s);

    union {
        std::uint64_t n;
        std::uint8_t a[8];
    } u;

    strm >> std::hex >> u.n;
    std::reverse(u.a, u.a + 8);

    std::cout << std::hex << std::setfill('0') << std::setw(16) << u.n << std::endl;
    return 0;
}
  • But the string is in little-endian, hex form. For example, the memory address 0x400678 is expressed as "7806400000000000". – RouteMapper Jul 15 '13 at 19:13
  • 1
    @RouteMapper Then you swap the bytes after the conversion. –  Jul 15 '13 at 19:16
  • Is there a well-known function for swapping bytes from a uint64_t type? – RouteMapper Jul 15 '13 at 19:19
  • 2
    @RouteMapper [Here's the math for 2 bytes](http://stackoverflow.com/questions/3916097/integer-byte-swapping-in-c), easily extensible for any number of bytes. But, if you are feeling lazy, then make an `union { uint64_t i; uint8_t a[8]; }`, then `std::reverse(u.a, u.a + 8)`. –  Jul 15 '13 at 19:22
  • How can you detect errors? e.g. if the string is `"ZZZ"`, this gives me 0, not a sort of error – Claudiu Oct 28 '14 at 16:12
  • @user529758 - You can't use a union like that in C++. It leads to [undefined behavior](http://stackoverflow.com/q/11373203/608639). Maybe `bswap` would be a better choice. – jww May 15 '17 at 00:32