I would not change the (global) flags of a stream, just a manipulator:
#include <iostream>
#include <iomanip>
#include <limits>
template <typename T>
struct Hex
{
// C++11:
// static constexpr int Width = (std::numeric_limits<T>::digits + 1) / 4;
// Otherwise:
enum { Width = (std::numeric_limits<T>::digits + 1) / 4 };
const T& value;
const int width;
Hex(const T& value, int width = Width)
: value(value), width(width)
{}
void write(std::ostream& stream) const {
if(std::numeric_limits<T>::radix != 2) stream << value;
else {
std::ios_base::fmtflags flags = stream.setf(
std::ios_base::hex, std::ios_base::basefield);
char fill = stream.fill('0');
stream << "0x" << std::setw(width) << value;
stream.fill(fill);
stream.setf(flags, std::ios_base::basefield);
}
}
};
template <typename T>
inline Hex<T> hex(const T& value, int width = Hex<T>::Width) {
return Hex<T>(value, width);
}
template <typename T>
inline std::ostream& operator << (std::ostream& stream, const Hex<T>& value) {
value.write(stream);
return stream;
}
int main() {
std::uint8_t u8 = 1;
std::uint16_t u16 = 1;
std::uint32_t u32 = 1;
std::cout << hex(unsigned(u8), 2) << ", " << hex(u16) << ", " << hex(u32) << '\n';
}
printf()
is short I can assure you it is anything but. You'll just need to roll your own (which will look shocking similar to what you have here). You could always write a manipulator class/operator pair that allows something likestd::cout << as_hex(n,8,0);
– Metrics#define PAD_HEX(digits) std::hex << std::setw(digits) << std::setfill('0')
then later in the code use it asstd::cout << "0x" << PAD_HEX(8) << my_int ..
– Herwig