使用ostream格式化自定义类型

时间:2016-11-17 08:56:00

标签: c++ ostream

我们可以使用不同的选项更改流行为:

std::cout << 0xfabadau << '\n';
std::cout << std::hex << std::setfill('0') << std::setw(8) << 0xfabadau << '\n';

输出:

16431834
00fabada

现在假设我有一个byte_buffer自定义类型:

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;
}

使用它我无法应用自定义格式::

byte_buffer b { 0xfau, 0xbau, 0xdau, };
std::cout << b << '\n';
std::cout << std::hex << std::setfill('0') << std::setw(8) << b << '\n';

上面的代码显示了以下输出:

fabada
000000fabada

<{1}}之外的std::setfillstd::setw 影响std::ostream &operator <<byte 的第一个byte_buffer std::ostream &operator <<因此观察到的输出,这不是意料之外的不是我想要的。我想要的输出是:

fabada
00fabada

如何更改std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer)以使byte_buffer按照我想要的方式行事?

2 个答案:

答案 0 :(得分:1)

你可以使用像这样的字节

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;
}

更灵活的方法

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();
}

答案 1 :(得分:1)

您可以随时获取标志并在您的功能中使用它们。例如(这里仅处理宽度)

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';
}