文字の行を読み取って、その文字に対応する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
を持ち、他の文字は持たないのですか?
ffffff
がシステムで署名されているため、char
が表示されています。 Cでは、printf
などの可変引数関数は、int
より小さいすべての整数をint
にプロモートします。 char
は整数(あなたの場合は8ビット符号付き整数)であるため、文字は符号拡張を介してint
に昇格されます。
c0
と80
の先頭には1ビットがあり(8ビット整数として負であるため)、サンプルのその他のものは符号拡張されていますが、符号拡張されています。
char int
c0 -> ffffffc0
80 -> ffffff80
61 -> 00000061
解決策は次のとおりです。
char ch = 0xC0;
printf("%x", ch & 0xff);
これにより、上位ビットがマスクされ、必要な下位8ビットのみが保持されます。
実際、intへの型変換があります。また、%hhx指定子を使用して、強制的に型をcharにできます。
printf("%hhX", a);
ほとんどの場合、2番目の文字をゼロで埋めるために最小長も設定する必要があります。
printf("%02hhX", a);
ISO/IEC 9899:201xのコメント:
7長さ修飾子とその意味は次のとおりです。hh次のd、i、o、u、x、またはX変換指定子が符号付き文字または符号なし文字引数に適用されることを指定します(引数は整数プロモーションに従って昇格されます。ただし、その値は印刷前に符号付き文字または符号なし文字に変換されます);または、次の
符号なし文字を作成できます:
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);
おそらく符号付き文字配列から印刷しています。符号なしchar配列から出力するか、0xffで値をマスクします。 ar [i]&0xFF。高(符号)ビットが設定されているため、c0値は符号拡張されています。