※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

バイナリデータを16進ダンプ(ヘキサダンプ)する関数を作ってみた。
C++を勉強し始めたので、C++らしくつくりたかったが、ただのC言語の関数になってしまった。
特定のデータと結びついてないのでクラスにするほどでもなく、書式指定での出力を使うのに、std::coutよりprintfの方が簡潔だったので。
そのうち使える機能を増やし、Utilityクラスでもつくってみよう。

■ソース
#include <stdio.h>
 
// 定数宣言
const int width = 16;            // 1行のダンプサイズ
const int binwidth = 4;          // 1行の区切りサイズ
 
int hexdump( char *buf, int bufsize){
  int num,i;
  int linesize;                  // 1行の表示対象データサイズ
  unsigned char binbuf[width];   // 1行に表示するバイナリデータ格納域
  unsigned char charbuf[width];  // 1行に表示するキャラクタデータ格納域
 
  // タイトル行
  printf("ADDRESS  0");
  for(i= 0; i < width; i++){
    printf("--");
    if(((i+1) % binwidth) == 0){
      if((i+1) == width){
        printf("%d CHARACTER\n",width);
      }else{
        printf("+");
      }
    }
  }
 
  // ダンプ出力
  for(num = 0; num < bufsize; num += width){
    //1行の表示対象データサイズを計算
    if((bufsize - num - width ) < 0){
      linesize = (bufsize - num) % width;
    }else{
      linesize = width;
    }
 
    // 出力用データ加工
    for(i=0; i < width; i++){
      if( linesize > i){
        if( buf[i] < 0x20 || buf[i] > 0x7e ){
          // 非可読文字なら.に置換
          charbuf[i] = '.';
        }else{
          charbuf[i] = *(buf+i);
        }
        binbuf[i] = *(buf+i);
      }else{
        // linsizeがwidth未満ならスペースに置換
        binbuf[i] = ' ' ;
        charbuf[i] = ' ';
      }
    }
 
    // アドレス出力
    printf("%08x ", num);
 
    // バイナリ部出力
    for(i= 0; i < width; i++){
      if( ((i) % binwidth) == 0){
        printf(" ");
      }
      if((bufsize - num ) > i ){
        printf("%02x", binbuf[i]);
      }else{
        printf("  ");
      }
    }
 
    // キャラクタ部出力
    printf("  *");
    for(i= 0; i < width; i++){
      printf("%c",charbuf[i]);
    }
    printf("*\n");
 
    buf += width;
  }
  return(0);
}
■使い方サンプル
int main() {
	int i;
	char dat[0x100];

	for(i = 0; i < 0x100; i++){
		dat[i] = i;
	}
	hexdump(dat,0x100);

	return 0;
}
■表示サンプル
ADDRESS  0--------+--------+--------+--------16 CHARACTER
00000000  00010203 04050607 08090a0b 0c0d0e0f  *................*
00000010  10111213 14151617 18191a1b 1c1d1e1f  *................*
00000020  20212223 24252627 28292a2b 2c2d2e2f  * !"#$%&'()*+,-./*
00000030  30313233 34353637 38393a3b 3c3d3e3f  *0123456789:;<=>?*
00000040  40414243 44454647 48494a4b 4c4d4e4f  *@ABCDEFGHIJKLMNO*
00000050  50515253 54555657 58595a5b 5c5d5e5f  *PQRSTUVWXYZ[\]^_*
00000060  60616263 64656667 68696a6b 6c6d6e6f  *`abcdefghijklmno*
00000070  70717273 74757677 78797a7b 7c7d7e7f  *pqrstuvwxyz{|}~.*
00000080  80818283 84858687 88898a8b 8c8d8e8f  *................*
00000090  90919293 94959697 98999a9b 9c9d9e9f  *................*
000000a0  a0a1a2a3 a4a5a6a7 a8a9aaab acadaeaf  *................*
000000b0  b0b1b2b3 b4b5b6b7 b8b9babb bcbdbebf  *................*
000000c0  c0c1c2c3 c4c5c6c7 c8c9cacb cccdcecf  *................*
000000d0  d0d1d2d3 d4d5d6d7 d8d9dadb dcdddedf  *................*
000000e0  e0e1e2e3 e4e5e6e7 e8e9eaeb ecedeeef  *................*
000000f0  f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff  *................*

■その他
 以下をいじると、表示桁数などを変更できる。
// 定数宣言
const int width = 32;								// 1行のダンプサイズ
const int binwidth = 8;								// 1行の区切りサイズ

ADDRESS  0----------------+----------------+----------------+----------------32 CHARACTER
00000000  0001020304050607 08090a0b0c0d0e0f 1011121314151617 18191a1b1c1d1e1f  *................................*
00000020  2021222324252627 28292a2b2c2d2e2f 3031323334353637 38393a3b3c3d3e3f  * !"#$%&'()*+,-./0123456789:;<=>?*


名前:
コメント: