0

这是代码:

std::wstringstream wss;    

wss.setf(std::ios_base::hex, std::ios_base::basefield);

wss.setf(std::ios_base::showbase);
// wss << std::showbase;

// wss.width(2);
wss.fill('0');

wss << std::setw(2) << 7;
// wss << std::noshowbase;
wss.unsetf(std::ios_base::showbase);
wss << std::setw(2) << 0;
wss << std::setw(2) << 20;
wss << std::setw(2) << 6;

auto ret = wss.str();

如果我showbase为流设置,我总是得到低于 output:
0x7001406,而不是0x07001406

我怎样才能在 7 点之前得到这个零?我不0x想像wss << "0x".

提前致谢!!

4

2 回答 2

2

感谢@Aconcagua 提供线索!

我认为我们可以使用std::ios_base::adjustfieldstd::ios_base::internal这样做:

wss.setf(std::ios_base::hex, std::ios_base::basefield);
int oldFlag = wss.setf(std::ios_base::internal, std::ios_base::adjustfield);

然后

wss.setf(std::ios_base::showbase);
wss.fill('0');

wss << std::setw(4) << 7;
wss.unsetf(std::ios_base::showbase);
//  wss.setf(oldFlag);

wss << std::setw(2) << 0;
wss << std::setw(2) << 20;
wss << std::setw(2) << 6;

然后我得到 0x07001406。如果我不能这样做,请纠正我,谢谢!

于 2018-07-16T09:38:41.460 回答
1

问题是:前缀是输出宽度的一部分!尝试wss << std::setw(4) << 7;比较(你现在得到00x7,这仍然是不需要的......)。

不幸的是,您不能使用precisionfor 整数来获得等效于 的行为printf("%#.2x\n", 7);,这显然是您想要的...

我的个人变体是拥有自己的转换器:

template <typename T>
struct Hex
{
    Hex(T value, size_t width) : value(value), width(width) { }
private:
    T value;
    size_t width;

    template <typename Stream>
    friend Stream& operator<<(Stream& s, Hex h)
    {
        auto fill = s.fill();
        auto flags = s.flags();
        s.fill('0');
        s << "0x" << std::noshowbase << std::hex << std::setw(h.width) << h.value;
        s.fill(fill);
        s.flags(flags);
        return s;

    }
};
template <typename T>
auto hex(T t, size_t width = sizeof(T) * 2) { return Hex<T>(t, width); }

您现在可以将其用作:

wss << hex(7, 2);

变得比拥有更短,wss << std::setw(2) << 7;并且带有适合类型大小的漂亮默认值......

还有一个小缺点:您需要对有符号和无符号字符进行特化或重载,对于这些,0x0s输出字符表示 ( ) 而不是数值 ( 0x73)。

auto hex(char t, size_t width = sizeof(char) * 2)
{ return Hex<unsigned int>(t, width); }
auto hex(signed char t, size_t width = sizeof(signed char) * 2)
{ return Hex<signed int>(t, width); }
auto hex(unsigned char t, size_t width = sizeof(unsigned char) * 2)
{ return Hex<unsigned int>(t, width); }

您可以在默认情况下替换2CHAR_BIT / 4,具体取决于您的需求/愿望,可能涵盖具有CHAR_BIT == 16更好...

于 2018-07-16T09:16:17.650 回答