Reputation: 13320
We can change the stream behaviour with different options:
std::cout << 0xfabadau << '\n';
std::cout << std::hex << std::setfill('0') << std::setw(8) << 0xfabadau << '\n';
Outputs:
16431834 00fabada
Now lets say I have a byte_buffer
custom type:
using byte = std::uint8_t;
using byte_buffer = std::vector<byte>;
std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer)
{
for (const auto &b : buffer) o << std::hex << int{b};
return o << std::dec;
}
Using it I cannot apply custom format::
byte_buffer b { 0xfau, 0xbau, 0xdau, };
std::cout << b << '\n';
std::cout << std::hex << std::setfill('0') << std::setw(8) << b << '\n';
The code above shows the following output:
fabada 000000fabada
The std::setfill
and std::setw
outside of the std::ostream &operator <<
is affecting the first byte
of byte_buffer
inside of the std::ostream &operator <<
hence the observed output, this isn't unexpected byt is not what I want. The output I want is:
fabada 00fabada
How should I change the std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer)
in order to make byte_buffer
behave the way I want?
Upvotes: 1
Views: 1942
Reputation: 119867
You can always get the flags and use them in your function however you want. For example (only dealing with the width here)
int width = o.width(), item_width;
int fill = o.fill();
if (width > 2*buffer.size())
item_width = width - 2*(buffer.size()-1);
else
item_width = 2;
for (const auto &b : buffer)
{
o << std::hex << std::setw(item_width) << setfill(fill) << int{b};
item_width = 2; fill = '0';
}
Upvotes: 2
Reputation: 323
You can work with byte something like this
std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer)
{
std::uint32_t temp=0;
for (const auto &b : buffer)
{
temp<<=8;
temp|=b;
}
return o << std::hex << temp << std::dec;
}
More flexible approach
std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer)
{
std::ostringstream ss;
for (const auto &b : buffer)
{
ss<< std::hex << int{b};
}
return o << ss.str();
}
Upvotes: 1