2009-11-20 7 views
7

これはちょっと奇妙な問題です。Cのchar *配列の16進値を出力すると、バイナリ入力のために奇数値が得られます

プログラムはC89で書かれており、freadとsizeof(char)のサイズを使って、一度に16バイトのchar *配列にファイルを読み込みます。このファイルは "rb"フラグ付きで表示されます。配列は、基本的に16進数の値を取り、文字列にスティックし、各値はスペースで区切られた関数に渡されます。

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

16進数の値はsprintf( "%02x" 、入力[i]);ループで。

一部のファイルでは正しく動作しますが、他のファイルでは正常に動作しないのはなぜですか?あなたが見る何

答えて

9

intcharから符号拡張、unsigned char *を使用するかであるint型にキャストする前にキャストunsigned char(暗黙的に?)あなたの問題を解決する必要があります行った結果です。

11

Cでは、charを符号なし値として指定しない限り、charは符号付き値として扱われます。関数にパラメータを渡すと、パラメータがcharになったときに、通常の整数のサイズにパディングされたように見えます。これが符号なしの方法で行われるべきであるという点でコンパイラを手がかりにしないと、128は0xFFFFFF80になります。

したがって、印字フォーマッタが値を見る前に符号拡張が行われます。これが意味すること

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

入力[I]の値として、あなたの問題を解決することはできません符号拡張されるので、128から255までのすべての値が-1に-127として扱わとなっている0xFFFFFF80 0xFFFFFFにキャストしますが、キャストは

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

となりますが、読みにくいです。まず、入力[]の型をunsigned charにすることをお勧めします。

関連する問題