【问题标题】:Pad leading zeroes in multiples of x, using std::cout << std::hex在 x 的倍数中填充前导零,使用 std::cout << std::hex
【发布时间】:2014-10-30 11:27:31
【问题描述】:

在使用带有我们希望以十六进制格式表示的变量的 C++ 流时,有很多关于 how to pad a fixed number of leading zeroes 的问题:

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 并返回所需的位数。

标签: c++ c++11 stdout number-formatting


【解决方案1】:

这个怎么样:

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 函数模板中。

【讨论】:

    【解决方案2】:

    没有立即支持它,因为它涉及更多 超过一个输入值(如果我了解您的要求 正确)。想到的唯一解决方案是使用 std::max求最大值,然后推导数 你需要的数字,比如使用表格:

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

    并查找其中的宽度。

    【讨论】:

    • 除了cout &lt;&lt; hex &lt;&lt; setw(8) &lt;&lt; 0x0,它在任何意义上都不会涉及多个输入。我要求的唯一区别是 8 的倍数。
    猜你喜欢
    • 2013-07-06
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 2017-12-23
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多