ostream showbase 不显示“0x";对于零值
PSPS:(预先编写好的后脚本)
我刚刚想到一个更有先见之明的问题将包括以下概念:对于零值整数,这种不显示0x"(showbase)是标准行为,还是只是我的 MinGW 实现的一个怪癖?
PSPS: (a Pre-scripted Post-script)
It has just come to mind that a more prescient question would have included the notion of: Is this non-display of "0x"(showbase) for zero-value integers a standard behaviour, or is it just a quirk of my MinGW implementation?
这一切都始于一个愉快的周日早晨......我想以十六进制表示形式转储一些句柄,并以一致的格式方式转储.
我想要一个前导 0x 和一个固定宽度,但事实证明,使用预期的流操纵器是难以捉摸的.
我发现这样做的唯一方法是将 Handles 转换为 unsigned long.这似乎有点不合理,我希望我不是唯一想要这个的人..
我是否遗漏了标准十六进制操纵器中的某些内容?是不是因为类型 void* (HANDLE) 只是在 ostream 的正常十六进制处理之外定义的?
It all began on a pleasant Sunday morning... I want to dump some Handles in their hex representation, and in a consistant, formatted way.
I want a leading 0x and a fixed width, but this is proving to be elusive using the expected stream manipulators.
The only way I've found to do this is to cast the Handles to an unsigned long.
This seems a bit unreasonable, and I would expect that I'm not the only person to have ever wanted this..
Am I missing something in the standard hex manipulators? Is it because type void* (HANDLE) is simply defined outside of the normal hex-handling of ostream?
总而言之:我不想将 HANDLE 强制转换为它不是的东西.
我不想硬编码0x"前缀.有没有办法使用标准操纵器来做到这一点?或者我是否需要重载 ostream 对 HANDLE 的处理?(但这可能会让我超负荷!)
In summary: I don't want to have to cast HANDLE to something which it isn't.
and I don't want to hard code a "0x" prefix. Is there a way to do it using standard manipulators? or would I need to overload ostream's handling of HANDLE? (but that might overload me!)
这是我的测试代码(及其输出).
我用过'.'作为填充字符,为了清楚起见,(我实际上将使用0")
Here is my test code (and its output).
I've used '.' as the fill char, for clarity, (I will actually be using '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
推荐答案
我在 上找到了这个https://bugzilla.redhat.com/show_bug.cgi?id=166735 - 这是直接从那里复制/粘贴的.
I found this on https://bugzilla.redhat.com/show_bug.cgi?id=166735 - this is copy/paste straight from there.
对我来说听起来不像是一个错误.ISO C++98, 22.2.2.2.2/10 说 std::showbase 意味着在 # printf 转换之前预选赛.22.2.2.2.2/7 说 std::hex 意味着 printf 转换说明符是%X.因此,恕我直言,行为必须与 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)."
Doesn't sound like a bug to me. ISO C++98, 22.2.2.2.2/10 says std::showbase means prepending # printf conversion qualifier. 22.2.2.2.2/7 says std::hex means the printf conversion specifier is %x. So the behaviour is IMHO required to be the same as printf ("%#x", 0); But http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html says: "For x or X conversion specifiers, a non-zero result shall have 0x (or 0X) prefixed to it." The same is in ISO C99, 7.19.6.1(6): "For x (or X) conversion, a nonzero result has 0x (or 0X) prefixed to it."
所以听起来像 C++98 标准(通过说'让它像 C 的 printf("%#x", 0)')需要你看到的这种愚蠢的行为.获得所需内容的唯一方法是摆脱 std::showbase 并显式输出 0x .对不起.
So it sounds like the C++98 standard (by saying 'make it like C's printf("%#x", 0)') requires this goofy behavior you're seeing. The only way to get what you want would be to get rid of the std::showbase and output 0x explicitly. Sorry.
相关文章