10

PSPS :( 事前にスクリプト化されたポストスクリプト)
より先見の明のある質問には、次の概念が含まれていることに気づきました。ゼロ値の整数に対する「0x」(showbase)の非表示は標準的な動作ですか。それとも私のMinGW実装の癖ですか?

それはすべて楽しい日曜日の朝に始まりました...私はいくつかのハンドルを16進表現で、一貫したフォーマットされた方法でダンプしたいと思います。先頭の0x固定幅
が 必要ですが、これは、予想されるストリームマニピュレータを使用するとわかりにくいことが証明されています。 これを行うために私が見つけた唯一の方法は、Handlesをunsignedlongにキャストすることです。これは少し不合理に思えます。これを望んでいたのは私だけではないと思います。標準の16進マニピュレーターに何かが足りないのでしょうか。タイプvoid*(HANDLE)は、ostreamの通常の16進処理の外で単純に定義されているためですか?

要約すると、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
4

2 に答える 2

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)のプレフィックスが付きます。」同じことがISOC99、7.19.6.1(6)にもあります。「x(またはX)変換の場合、ゼロ以外の結果には0x(または0X)のプレフィックスが付きます。」

したがって、C ++ 98標準(「Cのprintf( "%#x"、0)のようにする」と言うことで)は、あなたが見ているこの間抜けな振る舞いを必要とするように聞こえます。必要なものを取得する唯一の方法は、std :: showbaseを削除し、0xを明示的に出力することです。ごめん。

于 2010-07-18T16:07:37.820 に答える
7

値がゼロのときにstd::showbaseに「0x」がないという事実は時々厄介ですが、それはそれが定義されている方法であり、それについてあなたができることは何もありません:

std::cout << "0x" << .....

「0x」と残りの部分のギャップは修正可能ですが、推測するのは簡単ではありません。試す

std::cout << std::hex << std::showbase << std::setw(8) << std::setfill('0') << h;
于 2010-08-02T15:21:13.157 に答える