ostream showbase对于零值不显示"0x"

Pet*_*r.O 10 c++ formatting stream manipulators

PSPS :( 一个预先编写脚本的脚本)
刚刚想到一个更有先见之明的问题包括以下概念:这是否为零值整数的非显示"0x"(showbase)是标准行为,或者这只是我的MinGW实施的一个怪癖?

这一切都是在一个愉快的星期天早上开始的......我想以十六进制表示形式转储一些Handles,并采用一致的格式化方式.
我想要一个前导0x和一个固定宽度,但事实证明这是使用预期的流操纵器难以捉摸的.
我发现这样做的唯一方法是将Handles强制转换为unsigned long.这似乎有点不合理,我希望我不是唯一一个想要这个的人......
在标准六角形机械手中遗漏了什么?是因为类型void*(HANDLE)只是在ostream的正常十六进制处理之外定义?

总结:我不想将HANDLE强制转换为不是的东西.
我不想硬编码"0x"前缀.有没有办法使用标准操纵器?还是我需要重载ostream对HANDLE的处理?(但这可能使我超负荷!)

这是我的测试代码(及其输出).
我用过'.' 作为填充字符,为清楚起见,(我实际上将使用'0')

HANDLE h; 
ULONG ul; 
int iH = sizeof(h); // how many bytes to this void* type.
int iW = iH*2;      // the max number of hex digits (width).
int iW2= iW+2;      // the max number of hex digits (+ 2 for showbase "0x").
int iX = 4;         // the number of bits per hex digit.
int ib = iH*8;      // the max number bits in HANDLE (exponent).
int i;
std::cout<<std::setfill('.'); // I actually want '0'; 
                              //   the dot is for display clarity
for( i=0; i<=ib; i+=iX )
{ ul = (pow(2,i)-1);
  h  = (HANDLE)ul;
  std::cout
  <<"//  ul "        <<std::setw(iW2)<<std::hex <<std::showbase  <<std::internal <<ul
  <<"     h "        <<std::setw(iW2) /* hex,showbase,internal have no effect */ <<h
  <<"      I want 0x"<<std::setw(iW) <<std::hex <<std::noshowbase<<std::right    <<(ULONG)h
  <<std::endl;
}

//  ul .........0     h .........0      I want 0x.......0
//  ul 0x.......f     h .......0xf      I want 0x.......f
//  ul 0x......ff     h ......0xff      I want 0x......ff
//  ul 0x.....fff     h .....0xfff      I want 0x.....fff
//  ul 0x....ffff     h ....0xffff      I want 0x....ffff
//  ul 0x...fffff     h ...0xfffff      I want 0x...fffff
//  ul 0x..ffffff     h ..0xffffff      I want 0x..ffffff
//  ul 0x.fffffff     h .0xfffffff      I want 0x.fffffff
//  ul 0xffffffff     h 0xffffffff      I want 0xffffffff
Run Code Online (Sandbox Code Playgroud)

Geo*_*rge 11

我发现这对https://bugzilla.redhat.com/show_bug.cgi?id=166735 -这是复制/粘贴直接从那里.

对我来说听起来不是一个小虫.ISO C++ 98,22.2.2.2.2/10表示std :: showbase意味着预先添加#printf转换限定符.22.2.2.2.2/7表示std :: hex表示printf转换说明符是%x.所以行为是IMHO要求与printf相同("%#x",0); 但http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html 说:"对于x或X转换说明,一个非零的结果应为0x(或0X)前缀." 同样是在ISO C99,7.19.6.1(6): "对于X(或X)转换,非零结果具有0X(或0X)前缀."

因此,它听起来就像是C++ 98的标准(说"使它像C的printf('%#X’,0)")要求你看到这个愚蠢的行为.得到你想要的唯一方法是明确摆脱std :: showbase和输出0x.抱歉.


Mic*_*l J 6

std :: showbase在值为零时没有"0x"的事实有时很烦人,但这就是它的定义方式,除此之外你无能为力:

std::cout << "0x" << .....
Run Code Online (Sandbox Code Playgroud)

"0x"和其余部分之间的差距是可以修复的,但是猜测并不容易.尝试

std::cout << std::hex << std::showbase << std::setw(8) << std::setfill('0') << h;
Run Code Online (Sandbox Code Playgroud)