Integer to hex string in C++

397,891

Solution 1

Use <iomanip>'s std::hex. If you print, just send it to std::cout, if not, then use std::stringstream

std::stringstream stream;
stream << std::hex << your_int;
std::string result( stream.str() );

You can prepend the first << with << "0x" or whatever you like if you wish.

Other manips of interest are std::oct (octal) and std::dec (back to decimal).

One problem you may encounter is the fact that this produces the exact amount of digits needed to represent it. You may use setfill and setw this to circumvent the problem:

stream << std::setfill ('0') << std::setw(sizeof(your_type)*2) 
       << std::hex << your_int;

So finally, I'd suggest such a function:

template< typename T >
std::string int_to_hex( T i )
{
  std::stringstream stream;
  stream << "0x" 
         << std::setfill ('0') << std::setw(sizeof(T)*2) 
         << std::hex << i;
  return stream.str();
}

Solution 2

To make it lighter and faster I suggest to use direct filling of a string.

template <typename I> std::string n2hexstr(I w, size_t hex_len = sizeof(I)<<1) {
    static const char* digits = "0123456789ABCDEF";
    std::string rc(hex_len,'0');
    for (size_t i=0, j=(hex_len-1)*4 ; i<hex_len; ++i,j-=4)
        rc[i] = digits[(w>>j) & 0x0f];
    return rc;
}

Solution 3

Use std::stringstream to convert integers into strings and its special manipulators to set the base. For example like that:

std::stringstream sstream;
sstream << std::hex << my_integer;
std::string result = sstream.str();

Solution 4

You can do it with C++20 std::format:

std::string s = std::format("{:x}", 42); // s == 2a

Until std::format is widely available you can use the {fmt} library, std::format is based on (godbolt):

std::string s = fmt::format("{:x}", 42); // s == 2a

Disclaimer: I'm the author of {fmt} and C++20 std::format.

Solution 5

Just print it as an hexadecimal number:

int i = /* ... */;
std::cout << std::hex << i;
Share:
397,891

Related videos on Youtube

kryptobs2000
Author by

kryptobs2000

Updated on November 20, 2021

Comments

  • kryptobs2000
    kryptobs2000 about 1 year

    How do I convert an integer to a hex string in C++?

    I can find some ways to do it, but they mostly seem targeted towards C. It doesn't seem there's a native way to do it in C++. It is a pretty simple problem though; I've got an int which I'd like to convert to a hex string for later printing.

  • MSalters
    MSalters almost 12 years
    sizeof(your_type)*2 is a bit ugly; numeric_limits<your_type>::digits/4 is cleaner.
  • Kornel Kisielewicz
    Kornel Kisielewicz almost 12 years
    @MSalters - quite on the contrary. Test your suggestion on the int type ;)
  • Alan Turing
    Alan Turing almost 10 years
    @Kornel, great answer, but why template it? To support long int?
  • Kornel Kisielewicz
    Kornel Kisielewicz almost 10 years
    @LexFridman, to emit exactly the amount of hex digits as needed. Why emit 8 digits if the type is a uint8_t?
  • Alexander Oh
    Alexander Oh over 8 years
    a nice answer, but beware that to_string is part of the namespace std in C++11
  • Alex over 8 years
    @Alex yes, it is 2014 after all... heaven forbid we'll have to start dealing with C++14 soon.
  • ov7a almost 7 years
    WARNIG: this will not work for single byte because char is always threated as char
  • ShadowRanger
    ShadowRanger almost 7 years
    This doesn't really add to the existing answers, and it's pointless to explicitly clear the sstream (it will be destroyed when the function returns on the next line anyway). You could avoid the named hexStr entirely and just return sstream.str(); without clearing and get the same effect, reducing four lines of code to one.
  • parasrish
    parasrish almost 7 years
    when purpose of the forum is to understand the things and usage. being verbose is far better to provide clear picture, than saving lines. question was not on optimized code, and answer tries to give a modular-method way of dealing with such conversions. @ShadowRanger
  • Wolf
    Wolf over 6 years
    What is the purpose of sstream.clear();? The sstream object is automatically destroyed at the end of the scope, so return sstream.str(); would do it.
  • parasrish
    parasrish over 6 years
    sstream.clear will just clear the content, before stream ends with scope end (to clear any fail and eof flags with clear). Indeed, when the scope dies, with the life-span of the stream-variable, and therefore sstream.str can be used to return by value. [Reference : cplusplus.com/reference/ios/ios/clear/]
  • ruipacheco
    ruipacheco about 6 years
    Shouldn't you just return buf.str() ?
  • S.R
    S.R over 5 years
    Will this work for any type? I mean also double, float, uint8_t?
  • Wolf
    Wolf almost 5 years
    @S.R It works for integral types, not for double and float (and not for pointers)
  • Wolf
    Wolf almost 5 years
    ... a very pragmatic (but valid) mix of C and C++, I'm not sure about speed ... for my taste, it's a bit dense.
  • Foxcat385
    Foxcat385 almost 5 years
    I tried this and I got error error C2784: 'std::basic_ostream<_Elem,_Traits> &std::operator <<(std::basic_ostream<_Elem,_Traits> &,const std::_Smanip<_Arg> &)': could not deduce template argument for 'std::basic_ostream<_Elem,_Traits> &' from 'std::basic_string<char,std::char_traits<char>,std::allocato‌​r<char>>'
  • Foxcat385
    Foxcat385 almost 5 years
    Nevermind. Another line of code in my code caused the error. If only C++ compiler knew how to tell me at which line of code the problem is happening.
  • David Gausmann
    David Gausmann almost 5 years
    You also require #include <sstream>
  • DeveloperChris
    DeveloperChris over 4 years
    Thank you, brilliant answer. Bringing in a stream library 'just' to do this seems such a waste.
  • wcochran
    wcochran over 4 years
    If I am formatting multiple ints, It seems that std::setw needs to be output to the stream for every int, whereas std::hex, std::setfill, std::uppercase, ... only need to be sent to the output stream once. This seems inconsistent?
  • Lincoln
    Lincoln about 4 years
    in my testing std::to_string(i) does not print std::uint8_t integers as hex. I think this may have to have separate conditions for both uint8_t and int8_t types, since they need to be cast to larger integers.
  • Loss Mentality
    Loss Mentality about 4 years
    @Lincoln You are right. I don't know what I was doing at the time (months ago now) that made me thing to_string handled 8-bit ints. I even went back to the compiler version I think I was using back then, just to double check, but to_string didn't work as I said it did. So who knows? Anyway, thanks for catching this - I've edited answer to something that should work correctly.
  • Lightness Races in Orbit
    Lightness Races in Orbit about 4 years
    Could show off the width deduction with e.g. TEST_ASSERT(int_to_hex(short(0x12)) == "0012");
  • Mark Lakata
    Mark Lakata almost 4 years
    I would use std::cout<<std::hex<<i<<std::dec;, otherwise all integers that are streamed out later will be in hex. You don't need to do that for the other answers that use stringstream because the stream is discarded after it is used, but cout lives forever.
  • Ruslan
    Ruslan about 3 years
    This will still work unexpectedly for char (which is distinct from both uint8_t and int8_t in most implementations (where they are respectively unsigned char and signed char)).
  • Loss Mentality
    Loss Mentality over 2 years
    @ruslan Yes, also bool and wide char types all match std::is_integral and will not fail the assert. But since char is, per the std., a guaranteed unique type, as are the wide char types, you can handle all of them if desired (exceptions are un/signed char, which match the un/signed integral type of whatever width a byte is on the current machine - typically int8 - and so can't be filtered if you want to match ints of the same width as well). You can reject char, wide chars, bools by adding more terms to the the static_assert: ... && !std::is_same_v<char, T> && !std::is_same_v<bool, T> etc...
  • jaques-sam
    jaques-sam over 2 years
    This prints 0000FFFF for 0xFFFF. I prefer to have 0xFFFF as output.
  • Code Abominator
    Code Abominator over 2 years
    I expect this will annoy everyone else in your project since so few people ever think to << std:dec before pushing numbers into a stream. I thought was a widely known flaw in C++ streams?
  • Jason Aller
    Jason Aller over 2 years
    This does use some techniques not seen in the other answers. Can you please edit the answer to include some explanation of how and why it works?
  • Wade Wang
    Wade Wang over 1 year
    The header file is #include <boost/format.hpp>
  • Haseeb Mir over 1 year
    Boost doesn't come pre-installed that's why
  • Plater about 1 year
    @DrumM pass a 4 into the hex_len parameter then?

Related