I believe that what you want is something like this:
#include <iostream>
#include <iomanip>
#include <limits>
int main()
{
int ia = 42;
const auto save_flags = std::cout.flags();
std::cout
<< std::left
<< std::showbase
<< std::hex
<< std::uppercase
<< std::setfill('0')
<< std::setw(std::numeric_limits<decltype(ia)>::digits / 4)
<< ia
<< std::endl;
std::cout.flags(save_flags);
}
This will first of all save the existing flags of the std::cout
stream so that you can restore them later after you have manipulated them. Then it will print the number left aligned (std::left
) and it will show the base of the number you are printing (0X
for hex - this is the std::showbase
bit), it will print the number as hex (std::hex
) in uppercase (std::uppercase
) and it will use 0
to fill any missing digits (std::setfill('0')
up to your desired width (which I made the maximum number of digits for the given type - the std::setw(std::numeric_limits<decltype(ia)>::digits / 4)
bit). Finally we restore the previous flags of the stream so future prints get the normal (or at least previously set) flags.
C++23
Starting from C++23, you can get rid of iostreams and use the std::print
funtion for formatting and printing purposes.
#include <print>
#include <limits>
int main( )
{
int ia { 42 };
std::print( "{:0<#{}X}\n", ia,
std::numeric_limits<decltype( ia )>::digits / 4 );
}
Output:
0X2A000
Explanation: Here in "{:0<#{}X}\n"
, 0 is the fill character. < is the left alignment symbol. # adds 0X to the beginning of the number. And X is the format specifier for uppercase hex integer formatting.