使用std::cout << std::hex,在x的倍数中填充前导零

3

有很多关于使用C++流表达十六进制格式的变量时,如何填充固定数量的前导零的问题:(参考链接)

std::cout << std::hex << setfill('0') << setw(8) << myByteSizedVar;

我的问题是如何对非固定宽度进行操作,而是按某个固定量的倍数操作 - 很可能是8,因为当比较输出时我们可能希望:
0x87b003a
0xab07

为了便于比较宽度(虽然顶部更大,但是你尝试在脑海中进行按位比较?很容易混淆),可以进行宽度匹配。

0x87b003a
0x000ab07

不错,两个字节排列整齐美观。但我们只看到了7位——这并不是立即显而易见的(特别是如果是15/16、31/32等),可能导致我们误将上方视为负数(假定有符号)。

好的,我们可以像上面那样将宽度设置为8。

然而,当与一个32位字对比时:

0x000000000000000000000000087b003a
0x238bfa700af26fa930b00b130b3b022b

这取决于用途,如果处理的是硬件,其中顶部数字实际上没有32位字的上下文环境,那么它可能更加不必要,甚至会产生误导。

我想要的是自动将数字的宽度设置为8的倍数,例如:

std::cout << std::hex << std::setfill('0') << setWidthMultiple(8) << myVar;

例如以下结果:

0x00000000
0x388b7f62
0x0000000f388b7f62

这个怎么用标准库或最少的代码实现?没有像 Boost.Format 这样的东西。

标准库中不存在这样的功能,但是您可以很容易地编写一个小函数来使用 myVar 并返回所需的数字位数。 - Kerrek SB
2个回答

4
这个怎么样:
template <typename Int>
struct Padme
{
    static_assert(std::is_unsigned<Int>::value, "Unsigned ints only");

    Int n_;
    explicit Padme(Int n) : n_(n) {}

    template <typename Char, typename CTraits>
    friend
    std::basic_ostream<Char, CTraits> & operator<<(
        std::basic_ostream<Char, CTraits> & os, Padme p)
    {
        return os << std::setw(ComputeWidth(p.n_)) << p.n_;
    }

    static std::size_t ComputeWidth(Int n)
    {
        if (n <         0x10000) { return  4; }
        if (n <     0x100000000) { return  8; }
        if (n < 0x1000000000000) { return 12; }
        return 16;
    }
};

template <typename Int>
Padme<Int> pad(Int n) { return Padme<Int>(n); }

使用方法:

std::cout << pad(129u) << "\n";

通过一些额外的工作,您可以提供具有不同数字组大小、不同数字进位等版本。对于带符号类型,您可以将std::make_unsigned插入到pad函数模板中。


0

目前没有直接支持它的方法,因为它涉及到多个输入值(如果我正确理解了你的问题)。唯一想到的解决方案是使用std::max来找到最大值,然后从中推导出所需的数字位数,例如通过使用表格:

struct DigitCount
{
    unsigned long long maxValue;
    int digits;
};
static const DigitCount digitCount[] =
{
    {        255UL, 2 },
    {      65535UL, 4 },
    {   16777215UL, 6 },
    { 4294967295UL, 8 },
};

并查找其中的宽度。


它不涉及任何比 cout << hex << setw(8) << 0x0 更多的输入。我要求的唯一差异是8的倍数。 - OJFord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接