当使用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
那样的东西。
答案 0 :(得分: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
函数模板中。
答案 1 :(得分:0)
没有立即支持它,因为它涉及更多
超过一个输入值(如果我理解你的要求
正确)。想到的唯一解决方案是使用
std::max
找到最大值,然后导出数字
您需要的数字,例如使用表格:
struct DigitCount
{
unsigned long long maxValue;
int digits;
};
static const DigitCount digitCount[] =
{
{ 255UL, 2 },
{ 65535UL, 4 },
{ 16777215UL, 6 },
{ 4294967295UL, 8 },
};
并查看其中的宽度。