16進数への変換方法について教えてください。
#初歩的なことかもしれませんがどうしてもわかりません
void main(){
char hoge[]=てすと中;
char total[20];
sprintf(total,%X,hoge);
printf(%s\n,total);
}
とすると
16進数で
82c482b782c692.......
と表示されると思っていたのですが、うまくいきません。
なにがいけないのでしょうか?
また、どのようにしたらうまくhogeを16進に変換してバッファに
入れることができるのでしょうか?
知っている方は手段を教えてください。
おねがいします。
> うまくいきません。
どのようにうまくいかないのか書きましょう。
意図した結果が出なかったのなら、その間違えた結果をここに書くことで、回答の助け
となる場合があります。
今回は、出た結果が容易に予想できますので
> sprintf(total,%X,hoge);
配列名(この場合は hoge)はポインタと同等です。
この文は、以下の文と同じ意味を持ちます。
sprintf(total, %X, &hoge[0]);
> どのようにしたらうまくhogeを16進に変換してバッファに
> 入れることができるのでしょうか?
hoge の要素をひとつずつ変換していくしかないんじゃないでしょうか。
コードを載せてくださいってのは勘弁してください。
> 今回は、出た結果が容易に予想できますので
書いてる途中で送信しちまった…_| ̄|○
出た結果が容易に想像できますので、このまま回答させていただきます。
とでも読み替えてください。
シャノンさんありがとうございます。
(不足な質問で失礼しました。)
無事16進数への変換ができました。
ただ、
void main(){
char hoge[]=てすと;
char total[10]=";
char work[9];
memset(work,0,sizeof(work));
for(int i=0;i<strlen(hoge);i++){
sprintf(work,%X,hoge[i]);
strcat(total,&work[6]);
}
printf(%s\n,total);
}
という方法で16進を表示するようにしてみたのですが、
sprintf(work,%X,hoge[i]);
strcat(total,&work[6]);
という方法が正しいか(一般的か)非常に心配です。
みなさんはこのような場合、どのようにコーディングするのでしょうか?
よろしくお願いします。
いくつか指摘。
> char hoge[]=てすと;
> char total[10]=";
てすとのバイト数は2バイト×3=6バイト
1バイトが16進数2桁に変換されるので結果は12バイト
total のサイズが足りてません。
> strcat(total,&work[6]);
なぜ &work[6] ? と思いましたが、負の数対策ですか。
これは
sprintf(work,%X,(unsigned char)hoge[i]);
の方がよろしいかと。
それと、細かいことですが、sprintf の書式設定は %X よりも %.2X のほうがふさわし
いと思います。
> みなさんはこのような場合、どのようにコーディングするのでしょうか?
なんだか work が無駄な気がしたので、これを使用しないよう考えてみました。
最初は
sprintf( total, %s%.2X, total, ( unsigned char )hoge[ i ] );
のようなのを考えました。が、MSDN によれば
> 重なり合う文字列間でコピーした場合の動作は未定義です。
とありますので、あまり望ましくはないようです。
そこで、1バイトが16進数2桁に変換されることを利用して
sprintf( &total[ i * 2 ], %.2X, ( unsigned char )hoge[ i ] );
なんてのも考えました。参考にしてみてください。
#余談ですが
某所で見かけた変換法。sprintf を使いません。
あらかじめ
char hex[] = 0123456789ABCDEF;
を用意しておいて、sprintf の代わりに
total[ i * 2 ] = hex[ ( unsigned char )hoge[ i ] >> 4 ];
total[ i * 2 + 1 ] = hex[ ( unsigned char )hoge[ i ] & 15 ];
なんてのをやってました。
わかりにくいのでお勧めしませんが、sprintf よりはるかに高速です。
#あくまでも余談ですよ
一般的かはわからないですが、こんなのとか:
int len=strlen(hoge);
int written=0;
for(int i=0;i<len;++i)
written+=sprintf(total+written,%X,hoge[i]&0xFF);
Windows で日本語を扱う場合、ユニコードで無いのならマルチバイト(シフトJIS)
(文字列定数は)なので、文字列は char ではなく unsigned char の配列かポインター
として扱うと面倒が少なくなります。(シフトJISについてもう少し学んでください)
そうすると、strcat(work, &work[6]); なんていう判り辛(づら)いコードは書かなくて
も済むでしょう。(以下に示すのは、あくまでも参考のための例です)
int main(int, char **)
{
unsigned char hoge[]=てすと;
char total[256]="; ///// 少し位余ってもこの場合困らない
char work[9];
//memset(work,0,sizeof(work)); ///// これは無くても困らない
for(int i=0; i <strlen(hoge); i++) {
sprintf(work, %02X,hoge[i]);
strcat(total, work);
}
printf(%s\n, total);
return 0;
}
ご返答していいただいたみなさまありがとうございました。
大変参考になりました。
本当にありがとうございます。