7

これは私を少し困惑させている奇妙な問題です。

このプログラムはC89で記述されており、ファイルを一度に16バイトずつchar *配列に読み込みます(freadとsizeof(char)のサイズを使用)。ファイルは「rb」フラグでfopenされます。次に、配列は、基本的に16の16進値を受け取り、それを文字列に貼り付ける関数に渡されます。各値はスペースで区切られます。

ここで奇妙なことが起こります。この関数は、私が持っているテキストファイル入力に対して、一度に16バイトの素晴らしい16進ダンプを生成します。しかし、小さなビットマップイメージで試してみると、失敗します。88ではなくffffff88のような文字列で出力されてしまいます。

16進値は、sprintf( "%02x"、input [i]);を使用して出力文字列に配置されます。ループで。

一部のファイルではこれが正しく機能するのに、他のファイルでは機能しないのはなぜですか?

4

2 に答える 2

12

C では、unsigned として指定しない限り、char は signed 値として扱われます。パラメータを関数に渡すと、パラメータがたまたまcharの場合、通常の整数のサイズに「パディングアウト」されるようです。これが署名されていない方法で行われるべきであるという点でコンパイラに手がかりがない場合、128 は 0xFFFFFF80 になります。

したがって、符号拡張は、印刷フォーマッタが値を確認する前に発生します。これが意味することは、

printf("%02X", (unsigned) input[i]);

input[i] の値は符号拡張されるため、問題は解決しません。したがって、128 から 255 までのすべての値は -127 から -1 として扱われ、0xFFFFFF80 から 0xFFFFFF になり、キャストされますが、

printf("%02X", ((unsigned char *) input)[i] );

トリックを行いますが、ちょっと不格好で読みにくいです。最初に input[] の型を unsigned char にするのが最善です。

于 2009-11-20T22:19:42.873 に答える
9

表示されるのは、 to からの符号拡張の結果であり、int へのキャストが (暗黙的に?) 実行される前に to を使用またはキャストすると、問題が解決するcharはずintですunsigned char *unsigned char

于 2009-11-20T22:19:37.663 に答える