web-dev-qa-db-ja.com

Cでの16進文字の印刷

文字の行を読み取って、その文字に対応する16進数を出力しようとしています。

たとえば、最初の2文字が16進数の"0xc0 0xc0 abc123"で、残りの文字がASCIIのc0であるabc123の文字列がある場合、取得する必要があります

c0 c0 61 62 63 31 32 33

ただし、%xを使用したprintfは、

ffffffc0 ffffffc0 61 62 63 31 32 33

"ffffff"なしで必要な出力を取得するにはどうすればよいですか?そして、なぜc0(および80)だけがffffffを持ち、他の文字は持たないのですか?

83
Rayne

ffffffがシステムで署名されているため、charが表示されています。 Cでは、printfなどの可変引数関数は、intより小さいすべての整数をintにプロモートします。 charは整数(あなたの場合は8ビット符号付き整数)であるため、文字は符号拡張を介してintに昇格されます。

c080の先頭には1ビットがあり(8ビット整数として負であるため)、サンプルのその他のものは符号拡張されていますが、符号拡張されています。

char    int
c0 -> ffffffc0
80 -> ffffff80
61 -> 00000061

解決策は次のとおりです。

char ch = 0xC0;
printf("%x", ch & 0xff);

これにより、上位ビットがマスクされ、必要な下位8ビットのみが保持されます。

109
Mysticial

実際、intへの型変換があります。また、%hhx指定子を使用して、強制的に型をcharにできます。

printf("%hhX", a);

ほとんどの場合、2番目の文字をゼロで埋めるために最小長も設定する必要があります。

printf("%02hhX", a);

ISO/IEC 9899:201xのコメント:

7長さ修飾子とその意味は次のとおりです。hh次のd、i、o、u、x、またはX変換指定子が符号付き文字または符号なし文字引数に適用されることを指定します(引数は整数プロモーションに従って昇格されます。ただし、その値は印刷前に符号付き文字または符号なし文字に変換されます);または、次の

55
brutal_lobster

符号なし文字を作成できます:

unsigned char c = 0xc5;

印刷すると、C5ではなく、ffffffc5が得られます。

127よりも大きい文字のみがffffffで印刷されます。これは、それらが負であるためです(charが署名されています)。

または、印刷中にcharをキャストできます。

char c = 0xc5; 
printf("%x", (unsigned char)c);

おそらく、変数0xc0をchar変数(おそらく符号付き型)に格納しており、値は負(最上位ビットセット)です。次に、印刷時にintに変換され、意味的な同等性を維持するために、コンパイラは余分なバイトに0xffを埋め込みます。そのため、負のintは負のcharと同じ数値になります。これを修正するには、印刷時にunsigned charにキャストするだけです:

printf("%x", (unsigned char)variable);
11
lvella

おそらく符号付き文字配列から印刷しています。符号なしchar配列から出力するか、0xffで値をマスクします。 ar [i]&0xFF。高(符号)ビットが設定されているため、c0値は符号拡張されています。

2