16進表示について – プログラミング – Home

通知
すべてクリア

[解決済] 16進表示について


ココリコ
 ココリコ
(@ココリコ)
ゲスト
結合: 22年前
投稿: 3
Topic starter  

16進数への変換方法について教えてください。
#初歩的なことかもしれませんがどうしてもわかりません

void main(){
char hoge[]=てすと中;
char total[20];
sprintf(total,%X,hoge);
printf(%s\n,total);
}

とすると
16進数で
82c482b782c692.......
と表示されると思っていたのですが、うまくいきません。

なにがいけないのでしょうか?
また、どのようにしたらうまくhogeを16進に変換してバッファに
入れることができるのでしょうか?

知っている方は手段を教えてください。
おねがいします。


引用未解決
トピックタグ
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

> うまくいきません。
どのようにうまくいかないのか書きましょう。
意図した結果が出なかったのなら、その間違えた結果をここに書くことで、回答の助け
となる場合があります。

今回は、出た結果が容易に予想できますので

> sprintf(total,%X,hoge);
配列名(この場合は hoge)はポインタと同等です。
この文は、以下の文と同じ意味を持ちます。
sprintf(total, %X, &hoge[0]);

> どのようにしたらうまくhogeを16進に変換してバッファに
> 入れることができるのでしょうか?
hoge の要素をひとつずつ変換していくしかないんじゃないでしょうか。
コードを載せてくださいってのは勘弁してください。


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

> 今回は、出た結果が容易に予想できますので
書いてる途中で送信しちまった…_| ̄|○

出た結果が容易に想像できますので、このまま回答させていただきます。

とでも読み替えてください。


返信引用
ココリコ
 ココリコ
(@ココリコ)
ゲスト
結合: 22年前
投稿: 3
Topic starter  

シャノンさんありがとうございます。
(不足な質問で失礼しました。)

無事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]);
という方法が正しいか(一般的か)非常に心配です。
みなさんはこのような場合、どのようにコーディングするのでしょうか?

よろしくお願いします。


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

いくつか指摘。

> 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 ] );
なんてのも考えました。参考にしてみてください。


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

#余談ですが

某所で見かけた変換法。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 よりはるかに高速です。
#あくまでも余談ですよ


返信引用
n
 n
(@n)
ゲスト
結合: 23年前
投稿: 159
 

一般的かはわからないですが、こんなのとか:

int len=strlen(hoge);
int written=0;
for(int i=0;i<len;++i)
written+=sprintf(total+written,%X,hoge[i]&0xFF);


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

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;
}


返信引用
ココリコ
 ココリコ
(@ココリコ)
ゲスト
結合: 22年前
投稿: 3
Topic starter  

ご返答していいただいたみなさまありがとうございました。

大変参考になりました。
本当にありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました