プロが教えるわが家の防犯対策術!

こんにちは。

long型およびunsigned long型を
unsigned char型へ変換する方法を教えてください。

例えば、long型をchar型へ変換するには
sprintf(pchar, "%s", &longvalue);
で可能だと思いますが、冒頭の変換は
sprintfだと1番目の引数の型が違うようで
うまくいきません。

よろしくお願いします。

A 回答 (6件)

そもそも、longをunsigned charに変換するといっても、どうすることを想定しているかによって回答は変わります。



1.キャスト
long型の159(数値の159=0x0000009f)をunsigned char型の159(数値の159='0x9f')にする
long型の257(数値の257=0x00000101)をunsigned char型の1(数値の1=0x01)にする
signed long型の-1(数値の-1=0xffffffff)をunsigned char型の255(数値の255=0xff)にする

2.文字列へ変換
long型の159(数値の159=0x0000009f)をunsigned char型の"159"(文字列の"159"='1''5''9''0x00')にする

3a.バイトオーダ(リトルエンディアン)
long型の305419896(数値の305419896=0x12345678)をchar型配列の'0x78''0x56''0x34''0x12'にする
3b.バイトオーダ(ビッグエンディアン)
long型の305419896(数値の305419896=0x12345678)をchar型配列の'0x12''0x34''0x56''0x78'にする
4.バイトオーダ(ネットワークバイトオーダ)
long型の305419896(数値の305419896=0x12345678)をchar型配列の'0x12''0x34''0x56''0x78'にする

上記の各パターンで方法がそれぞれ違います。

int i;
long l;
long nl;
unsigned char uc;
char *cp;
unsigned char *ucp;
unsigned char ucbuf[16];

1.uc = (unsigned char)l;
別に明示的にキャストしなくても、暗黙のキャストにより結果は同じだが、明示的にキャストしたほうが読み間違えたりしないでしょう。

2.sprintf(ucbuf, "%ld", l);
sprintfはそれほど速くないが、頭を抱えるほど遅いわけでもないのでよいでしょう。
コード例は以下
l=159;
sprintf(ucbuf, "%ld", l);
printf(ucbuf, "ucbuf := %s\n", ucbuf);
for(i=0;i<16;i++)
{
printf("ucbuf[%d] := 0x%x\n", i, ucbuf[i]);
if(ucbuf[i] == 0x00) break;
}
結果:
ucbuf := 159
ucbuf[0] := 0x31
ucbuf[1] := 0x35
ucbuf[2] := 0x39
ucbuf[3] := 0x0

3.ホストバイトオーダ
これは、CPUのエンディアンに依存します。
コード例は以下
インテル系(リトルエンディアン)
l=0x12345678;
ucp = (unsigned char *)&l;
for(i=0;i<sizeof(long);i++) printf("ucp[%d] := 0x%x\n",i , ucp[i]);
結果:
ucp[0] := 0x78
ucp[1] := 0x56
ucp[2] := 0x34
ucp[3] := 0x12

モトローラ系(ビッグエンディアン)
l=0x12345678;
ucp = (unsigned char *)&l;
for(i=0;i<sizeof(long);i++) printf("ucp[%d] := 0x%x\n",i , ucp[i]);

結果:
ucp[0] := 0x12
ucp[1] := 0x34
ucp[2] := 0x56
ucp[3] := 0x78

ネットワークバイトオーダ(ビッグエンディアン)*1
#include <sys/param.h>

l=0x12345678;
nl = htonl(l);
ucp = (unsigned char *)&nl;
for(i=0;i<sizeof(long);i++) printf("ucp[%d] := 0x%x\n",i , ucp[i]);

結果:
ucp[0] := 0x12
ucp[1] := 0x34
ucp[2] := 0x56
ucp[3] := 0x78

*1 ネットワークバイトオーダはCPUがインテルでもモトローラでも同じになります。
    • good
    • 2

> b=a; ←このままではだめですよね…



union{
unsigned char tmp[sizeof(long)];
long a;
};

a=50;

> long型をchar型へ変換するには
これは「long型をバイト単位で分解するには」ですよね?
    • good
    • 0

> ...C++ソースですと、


>「1番目の引数を'unsigned char [100]'から'char *'に変換できません。」
> というコンパイルエラーが出てしまいます。

sprintf(reinterpret_cast<char*>(temp), "%ld",50L);

> unsigned char temp[100];
> long a= 50;
> memcpy(temp, &a, (size_t)a);
> これだと問題ありでしょうか?

そんな質問はまず自分で試してから。
    • good
    • 0

>long型およびunsigned long型を


>unsigned char型へ変換する方法を教えてください。

はNo1さんの回答が答えを見るとして。

>追加の質問で申し訳ないのですが、
>同様にcharの配列型に変換するにはどうすればよいで>しょうか。

>long a;
>unsigned char b[10];

>b=a; ←このままではだめですよね…

>すみませんが、よろしくお願いします。

これについては
以下のソースが答えです。

#include<stdio.h>

int main(int argc, char** argv)
{
unsigned char temp[100];
sprintf(temp, "%ld", 50L);
printf("%s\n", temp);
return 0;
}

この回答への補足

ご回答ありがとうございます。

上記の方法で試したところ、Cソースではコンパイルが通るのですが、C++ソースですと、
「1番目の引数を'unsigned char [100]'から'char *'に変換できません。」
というコンパイルエラーが出てしまいます。

unsigned char temp[100];
long a= 50;

memcpy(temp, &a, (size_t)a);

これだと問題ありでしょうか?

補足日時:2005/05/20 12:25
    • good
    • 0

> 例えば、long型をchar型へ変換するには


> sprintf(pchar, "%s", &longvalue);
> で可能だと思いますが、

ぜんぜん違います。 やってみてください。
    • good
    • 0

単純に転送すれば良いです。


long a;
unsigned char b;
b=a;
でOKです。
但し、bは0~255までしか、格納できませんので
転送もとのaも0~255迄の範囲でないと、期待した結果は得られません。

この回答への補足

ご回答ありがとうございます。

追加の質問で申し訳ないのですが、
同様にcharの配列型に変換するにはどうすればよいでしょうか。

long a;
unsigned char b[10];

b=a; ←このままではだめですよね…

すみませんが、よろしくお願いします。

補足日時:2005/05/20 11:10
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A