C言語関係掲示板

過去ログ

No744 16進ダンプを行いたい

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

16進ダンプを行いたい
投稿者---つぐ(2003/09/10 11:21:40)


はじめまして、16進ダンプを取るプログラムで悩んでおります。
実現したいことは、64バイト分のバッファを16進コードに変換する
ことです。
バッファの内容が64バイト未満の場合は不足分を0x00で埋めます。
以下のサンプルは稚拙で大変お恥ずかしいのですが、まず初めに
気づくのが先頭の'\0'(0x00)が後ろのコードと結びつき、意図した
0x00 と異なる表示がされてしまいます。
もう一つの問題点として、途中からおかしな表示となってしまいます。
よろしく、お願いいたします。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void CharToHex(char *s1,char *s2,size_t n){
  char *p=s1,*s=s2;
  char tempBuff[16];
  int inc=0;

  while(n>0){
    memset(tempBuff,'\0',16);
    inc=sprintf(tempBuff,"%02d:%02X:%c ",64-n,(*s)&0xff,*s);
    printf("%02d:%02X:%c ",64-n,(unsigned char)(*s)&0xff,*s);
    strncat(p,tempBuff,inc);
    s++;
    p=p+inc;
    n--;
  }
}

void main(int argc,char *argv[]){
  char logBuff[]="\00123456789\t\n0123456789\00123456789";

  char binBuff1[256];
  char binBuff2[256];

  memset(binBuff1,'\0',256);
  memset(binBuff2,'\0',256);

  memcpy(binBuff1,logBuff,64);
  CharToHex(binBuff2,binBuff1,64);

//  printf("[%s]\n",binBuff2);

  exit(0);
}


No.9252

Re:16進ダンプを行いたい
投稿者---JUN2(2003/09/10 12:01:22)


最終的な表示(出力)例を書いて。

No.9253

Re:16進ダンプを行いたい
投稿者---つぐ(2003/09/10 12:33:38)


>最終的な表示(出力)例を書いて。

00303132333435363738390030313233343536373839

最初から、0x00,0x30,...と言った並びを上記のような単純な出力で結構です。
書き忘れましたが、OS は Windows2000、コンパイラは VC++6.0 sp5 です。
よろしく、お願いします。

No.9254

Re:16進ダンプを行いたい
投稿者---nop(2003/09/10 13:03:20)


>char logBuff[]="\00123456789\t\n0123456789\00123456789";

この指定ですが、「\0」はリテラル中の 8 進表記の 0 を表します。
つまり、「\0」の後に数字が続くと、
「\xxx」(xは 8 進数字)とした 8 進数値として変換されます。
おそらく最初の「\0」は 0x00 を入れたいものと思われるため、
「\000」や「\x00」等と指定するべきでしょう。

で、16 進ダンプですが、
以下の感じでどうでしょう?
参考にはなるかと思います。

#include    <stdio.h>
#include    <stdlib.h>
#include    <time.h>

/* ************************************************************
    関数名【 DispDump() 】
        ダンプリスト表示処理関数
    処理概要
        指定されたメモリの内容を 16 進数ダンプ表示する
    引数
        1) aArea = 表示メモリ
        2) aSize = 表示バイト数
    戻り値
        なし
************************************************************ */
void    DispDump( const void *aArea, int aSize )
{
    /* ***** 内部変数定義 ***** */
    const unsigned char    *iBuf = (const unsigned char *)aArea;
    int                    i;

    for( i=0; i<aSize; i++ )
    {
        if( i )    /* インデックスは 0 以外か? */
        {
            /* ***** 区切り文字表示 ***** */
            printf( "%s", ( i%16 ) ? ( (i%16==8)?" - ":" " ) : "\n" );
        }
        /* ***** 16 進数データ表示 ***** */
        printf( "%02X", iBuf[i] );
    }
    /* ***** 改行表示 ***** */
    putchar( '\n' );
}

int main( void )
{
    /* ***** 内部変数定義 ***** */
    char    buf[64] = {'\0'};
    int     i;

    /* ***** 乱数初期化 ***** */
    srand( time(NULL) );

    for( i=0; i<sizeof(buf); i++ )
    {
        /* ***** 乱数設定 ***** */
        buf[i] = (char)(rand()>>8);
    }
    /* ***** ダンプ表示 ***** */
    DispDump( buf, sizeof(buf) );

    return 0;
}



No.9259

Re:16進ダンプを行いたい
投稿者---つぐ(2003/09/10 14:32:52)


>>char logBuff[]="\00123456789\t\n0123456789\00123456789";
>
>この指定ですが、「\0」はリテラル中の 8 進表記の 0 を表します。
>つまり、「\0」の後に数字が続くと、
>「\xxx」(xは 8 進数字)とした 8 進数値として変換されます。
>おそらく最初の「\0」は 0x00 を入れたいものと思われるため、
>「\000」や「\x00」等と指定するべきでしょう。

確かにそのとおりで、8進拡張表記としてC言語辞典に載っていました。

>で、16 進ダンプですが、
>以下の感じでどうでしょう?
>参考にはなるかと思います。

早速、参考にさせていただいて、自分なりのサンプルにしてみました。
表示は、8バイトおきに空白を入れるとの事で以下のように変更しました。
ありがとうございました。失礼します。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ************************************************************
    関数名【 DispDump() 】
        ダンプリスト表示処理関数
    処理概要
        指定されたメモリの内容を8バイトずつ16進数ダンプ表示する
    引数
        1) aArea = 表示メモリ
        2) aSize = 表示バイト数
    戻り値
        なし
************************************************************ */
void DispDump(const void *aArea,int aSize){
  /* ***** 内部変数定義 ***** */
  const unsigned char *iBuf=(const unsigned char *)aArea;
  int i;

  for(i=0;i<aSize;i++){
    if(i){  /* インデックスは 0 以外か? */
      /* ***** 区切り文字表示 ***** */
      printf("%s",((i%8)?"":" " ));
    }
    /* ***** 16 進数データ表示 ***** */
    printf("%02X",iBuf[i]);
  }
  /* ***** 改行表示 ***** */
  putchar('\n');
}

int main(void){
  /* ***** 内部変数定義 ***** */
  char buf[64]={'\0'};
  char logBuf[]="\000123456789\t\n0123456789\000123456789";

  /* ** 64バイト以下対応 ** */
  if(sizeof(logBuf)-1>64) memcpy(buf,logBuf,64);
  else                    memcpy(buf,logBuf,sizeof(logBuf)-1);
  

  /* ***** ダンプ表示 ***** */
  DispDump(buf,sizeof(buf)-1);

  return 0;
}


No.9260

Re:16進ダンプを行いたい
投稿者---nop(2003/09/10 14:41:23)


>DispDump(buf,sizeof(buf)-1);

なぜに「-1」しているのでしょうか?
これでは 63 バイト分しか表示されないのでは?

No.9268

Re:16進ダンプを行いたい
投稿者---つぐ(2003/09/10 17:47:10)


>>DispDump(buf,sizeof(buf)-1);
>
>なぜに「-1」しているのでしょうか?
>これでは 63 バイト分しか表示されないのでは?

10年程前に購入した技術評論社の ANSI C言語辞典よりお答えします。
以下のコードを実行比較してみて下さい。

printf("文字列長:%d\n",strlen("1234567890");
printf("配列長 :%d\n",sizeof("1234567890");

結果は、以下のようになると思います。

文字列長:10
配列長 :11

私は、末尾に付く'\0'がいらなかったので-1しました。




No.9269

Re:16進ダンプを行いたい
投稿者---nop(2003/09/10 17:56:11)


>私は、末尾に付く'\0'がいらなかったので-1しました。

最初の投稿内容にある

>はじめまして、16進ダンプを取るプログラムで悩んでおります。
>実現したいことは、64バイト分のバッファを16進コードに変換することです。

と言う記述と違いませんか?と言うことなのですが…。(^^;
まあ、問題は解決したようなので、別にどうでもいいんですが…。

No.9255

Re:16進ダンプを行いたい
投稿者---JUN2(2003/09/10 13:19:25)


レスが付いたみたいなので、更に質問があった時に答えられれば
書き込みます。