C言語関係掲示板

過去ログ

No891 unsigned char code = 0xFF を "256" にしたい

[戻る] [ホームページ]
No.480

unsignedについて
投稿者---初心者(2003/10/02 12:51:01)


sprintf()を使ってバイナリーで格納されている数値データをchar型の文字列に
変換したいのですが、sprintf(buf ,"%d",i); とやっても符号付の文字列になってしまいます。(例 0xFF → "−1")
i をunsigned int で宣言しても同じです。どうすればよいのでしょうか?教えてください。

No.481

Re:unsignedについて
投稿者---nop(2003/10/02 13:28:52)


>sprintf()を使ってバイナリーで格納されている数値データをchar型の文字列に
>変換したいのですが、sprintf(buf ,"%d",i); とやっても符号付の文字列になってしまいます。(例 0xFF → "−1")
>i をunsigned int で宣言しても同じです。どうすればよいのでしょうか?教えてください。

「"%d"」の書式は渡された引数を「int」型と見なし整数文字列に変換します。
符号無し整数値として変換したい場合は、「"%u"」の書式になります。

# でも、0xFF なら int 型でも 255 になります。
# どのようなソースで確認しているのでしょうか?

No.482

Re:unsignedについて
投稿者---初心者(2003/10/02 13:51:57)


>>sprintf()を使ってバイナリーで格納されている数値データをchar型の文字列に
>>変換したいのですが、sprintf(buf ,"%d",i); とやっても符号付の文字列になってしまいます。(例 0xFF → "−1")
>>i をunsigned int で宣言しても同じです。どうすればよいのでしょうか?教えてください。
>
>「"%d"」の書式は渡された引数を「int」型と見なし整数文字列に変換します。
>符号無し整数値として変換したい場合は、「"%u"」の書式になります。
>
># でも、0xFF なら int 型でも 255 になります。
># どのようなソースで確認しているのでしょうか?

回答ありがとうございます。
まず、char型データとバイナリデータが混ざった、文字列(電文)をつくり、そこからデータを取り出すテストプログラムです。

//テスト電文の作成
unsigned char code = 0xFF;
sprintf( testbuf, "12345%c6789", code );

//電文からデータの取り出し
sprintf( workbuf, "%04d", testbuf+5 );
//結果の確認
printf("結果コード :[%s]\n",workbuf );


=========================
255 という結果を取り出したいのです、必ず -1 になってしまいます・・・。
128以下なら普通に取りだせます。(結果は 0128)




No.483

Re:unsignedについて
投稿者---nop(2003/10/02 14:07:07)


> sprintf( workbuf, "%04d", testbuf+5 );

"%d"指定で char 型のデータを渡すのが間違い。
この場合、char 型から int 型への暗黙の型変換が行われます。

0xFF は singed char 型で値としては -1 に相当する処理系なのでしょう。
singed char 型の -1 を singed int 型に型変換されれば、
当然、変換後の結果も -1 です。

unsigned int でキャストし、0xFFU との論理積を取れば大丈夫でしょう。

No.484

Re:unsignedについて
投稿者---初心者(2003/10/02 14:28:32)


>> sprintf( workbuf, "%04d", testbuf+5 );
>
>"%d"指定で char 型のデータを渡すのが間違い。
>この場合、char 型から int 型への暗黙の型変換が行われます。
>
>0xFF は singed char 型で値としては -1 に相当する処理系なのでしょう。
>singed char 型の -1 を singed int 型に型変換されれば、
>当然、変換後の結果も -1 です。
>
>unsigned int でキャストし、0xFFU との論理積を取れば大丈夫でしょう。

回答有難うございます。ですが、ちょっと私には難しくて・・・。
根本になっている不明点を聞いてもよろしいでしょうか?

unsigned char code = 0xDE;

printf("code 16進 :[%x]", code ); //当然「DE」と表示されます。

sprintf(testbuf, "12345%c",code);
printf("テストバッファ][%s]",testbuf);
//当然0xDEのアスキーに対応した文字が付加されて表示されます。
//この場合「12345"」と表示されます。

printf("テストバッファ16進 :[%x]", testbuf+5);
//この場合も「DE」と表示されると思うのですが、
//「FFFFDE」と表示されます。
これはなんででしょうか?さっぱりわかりません・・・・。



No.485

Re:unsignedについて
投稿者---nop(2003/10/02 14:45:49)


>printf("テストバッファ16進 :[%x]", testbuf+5);
>//この場合も「DE」と表示されると思うのですが、
>//「FFFFDE」と表示されます。
>これはなんででしょうか?さっぱりわかりません・・・・。

これは char から int へ型変換する際の符号拡張の影響です。

0xDE = 0b11011110(=-34) → 0x111111111111111111011110 = 0xFFDE(=-34)

と最上位の符号ビットが拡張されて型変換されます。
(int=32bit、singed の最上位ビットが符号ビットの場合)

# 環境が違えば当然結果も変わってくるでしょう。

No.486

Re:unsignedについて
投稿者---初心者(2003/10/02 16:26:24)


>>printf("テストバッファ16進 :[%x]", testbuf+5);
>>//この場合も「DE」と表示されると思うのですが、
>>//「FFFFDE」と表示されます。
>>これはなんででしょうか?さっぱりわかりません・・・・。
>
>これは char から int へ型変換する際の符号拡張の影響です。
>
>0xDE = 0b11011110(=-34) → 0x111111111111111111011110 = 0xFFDE(=-34)
>
>と最上位の符号ビットが拡張されて型変換されます。
>(int=32bit、singed の最上位ビットが符号ビットの場合)
>
># 環境が違えば当然結果も変わってくるでしょう。

nopさん、いろいろ有難うございました。
なんとか解決することができました。

No.494

Re:unsignedについて
投稿者---かずま(2003/10/04 14:27:32)


> unsigned char code = 0xDE;
>
> printf("code 16進 :[%x]", code ); //当然「DE」と表示されます。
>
> sprintf(testbuf, "12345%c",code);
> printf("テストバッファ][%s]",testbuf);
> //当然0xDEのアスキーに対応した文字が付加されて表示されます。
> //この場合「12345"」と表示されます。
>
> printf("テストバッファ16進 :[%x]", testbuf+5);
> //この場合も「DE」と表示されると思うのですが、
> //「FFFFDE」と表示されます。
> これはなんででしょうか?さっぱりわかりません・・・・。

testbuf は sprintf の第1引数ですから、おそらく char testbuf[100];
のように宣言されているのでしょう。それなら、printf の testbuf+5 は
char * です。char ではありません。したがって、code の 0xDE ではなく、
偶然 testbuf+5 が 0xFFFFDE というアドレスだったのでしょう。char が
符号拡張したのだったら、FFFFDE ではなく、FFFFFFDE または FFDE と
表示されるはずです。

testbuf の宣言はどうなっているのでしょうか? こういう質問をする場合は
プログラムを省略せず、そのままコピー & ペーストしたほうがよいでしょう。

出力結果についてもそうです。0xDE を表示させると半角カタカナの「゙」が
出るはずなのに、あなたは「//この場合「12345"」と表示されます。」と
まちがった出力結果を書いています。