ダンププログラムについて教えてください

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
( ゚д゚ )

ダンププログラムについて教えてください

#1

投稿記事 by ( ゚д゚ ) » 14年前

Ascllのところに日本語も表示できるようにしたいのですがどうすればいいのですか?

~~~~~~~~~~~~~~
if(data < 0x20 || data >= 0x7F){
buff = '.';
else{
buff = data;
printf( "%02X ", data );
}
~~~~~~~~~~~~~~

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ダンププログラムについて教えてください

#2

投稿記事 by softya(ソフト屋) » 14年前

文字コードがわからないと処理出来ないので、OSの種類や詳細な開発環境の限定をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: ダンププログラムについて教えてください

#3

投稿記事 by ( ゚д゚ ) » 14年前

OS:Windows7
開発環境:VC 2008 コマンドプロントで作成
です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ダンププログラムについて教えてください

#4

投稿記事 by softya(ソフト屋) » 14年前

特に何もせず日本語環境でfread()したと想定すれば文字コードはshift-jisであろうと思われます。
なので、Shift-jisの全角コードであるか判定すれば2バイト文字なのか1バイト文字なのかは区別できます。

「C言語プログラミングの質問です。 文字コードの全角・半角判定で悩んでいます。 - Yahoo!知恵袋」
http://detail.chiebukuro.yahoo.co.jp/qa ... 1116019231
「半角と全角の混在するShiftJIS文字コードの扱い方(C/C++) - プログラミング講座 - fuku研究所」
http://www5f.biglobe.ne.jp/~fuku-labo/l ... /2/076.htm
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: ダンププログラムについて教えてください

#5

投稿記事 by ( ゚д゚ ) » 14年前

ありがとうございます。
日本語で表示することができました。

あともう一つ聞きたいのですが、16個目のデータが2バイト(漢字、全角文字など)だった場合、改行前に1バイト、改行後に1バイト表示してしまいます。
改行前に2バイトを表示したいのですがうまいくいきません。

現在のプログラムはこんな感じです

コード:

#include <stdio.h>
#include <conio.h>

void main()
{
	FILE	*fp;
	int	data;
	int _data;

	int	i;
	int end = 0;

	unsigned long addr;

	char	buf[100];

	while(1)
	{
		getch();
		// 実際にはgetchでファイル名を入力させ文字に変換し、
		// ファイル名とします
		// 今は、関係ないから直接読み込んでます

		// ファイルを開く
		fp = fopen("main.cpp", "rb");
		if(fp == NULL)
		{
			printf("ファイルがオープンできません.\n");        
			return;
		}
		// データの終わりまでロード
		for(addr = 0; end!=1; addr += 16)
		{
			printf("%08lX  ", addr);

			// 16進データ
			for(i = 0; i < 16; i++)
			{
				// 1バイト読み込み
				if((data = getc(fp) ) == EOF)
				{
					buf[i] = '\0';
					for(;i < 16; i++)
					{
						printf("   ");
					}
					printf("  %s\n", buf);
					fclose(fp);
					end=1;
					return;
				}

				if( data < 0x80 )
				{ 
					// 制御文字なら
					if( data < 0x20 )
					{ 
						buf[i]='.';	// .を代入 
					}         
					else			// 英数字なら
					{ 
						buf[i] = data;	// そのまま 
					}
				}
				// 0x80以上
				else
				{
					// 半角カナ
					if( (data>0x9F)&&(data<0xE0) )
					{ 
						buf[i] = data;	// そのまま
					}
					// 2バイト文字の1バイト目なら・・
					else
					{ 
						buf[i] = data;	// 1バイト目を代入
					}
				}
				
				printf("%02X ", data);
			}
			buf[i] = '\0';
			printf("  %s\n", buf);
		}
	}
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ダンププログラムについて教えてください

#6

投稿記事 by softya(ソフト屋) » 14年前

1バイトづつ読んでいるので面倒だと思います。
mallocしたメモリにファイル内容一括読み込み後に処理してはどうでしょうか?
※ その場合次の行の先頭は何らかの表示できない文字扱いが必要ですが。
[補足] あるいは、最後が2バイト文字の先頭ならその行だけ17バイト表示して次の行は15バイト表示するとか変則的な処理が必要です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: ダンププログラムについて教えてください

#7

投稿記事 by ( ゚д゚ ) » 14年前

mallocだとメモリ以上のファイルを読み込めないのであまりつかいたくありません。

16個目のデータが、2バイト文字(日本語)が1バイト目か2バイト目かわかればいけそうなのですが、なにかよい調べかはありませんか?

コード:

// 半角カナ
                    if( (data>0x9F)&&(data<0xE0) )
                    { 
                        buf[i] = data;  // そのまま
                    }
                    // 2バイト文字の1バイト目なら・・
                    ※これでは1バイト目でも2バイト目でも条件が成立してしまう
                    else

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ダンププログラムについて教えてください

#8

投稿記事 by softya(ソフト屋) » 14年前

今時メモリで困るとも思えませんが制御は面倒になります。
(1)16バイト目で2バイト文字の先頭なら次の1バイトをfgetcする。
(2)もし、それがEOFならこの行を表示して終了する。2バイト文字の先頭しか無かったので該当文字なし"."とする。
(3)読み込めた場合は、bufに追加。
(4)ここで次の行の1バイト目を読み込んでいる事になるので、次の行の先頭としての読み込みは行わないで処理する。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: ダンププログラムについて教えてください

#9

投稿記事 by ( ゚д゚ ) » 14年前

ありがとうございます。
うまくいったと思ったのですが・・
読み込むデータが
a.txt
あaいiうuえeおoかきくけこさしすせそ

だった場合「か」は改行前と改行後でデータが分かれてますが改行前で表示できています。
改行後に2バイト文字の2バイト目が表示されないようにもできました。

ですが、読み込むデータが

a.txt
阿鋳鵜得御下記九毛個沙師巣背祖(表示する行が16バイトできっちりおさまる場合)

だった場合

「阿鋳鵜得御下記九」までは普通に表示されるのですが「九」の横に「・」が表示され
2行目からは「_ム個沙師巣背祖」と表示されます。
※_はスペースです。

「16バイト目で2バイト文字の先頭なら」条件式がわかりません。
なにか特別な関数があるのでしょうか?

コード:

#include <stdio.h>
#include <conio.h>
#include <mbctype.h>

void main()
{
	FILE	*fp;
	int	data;
	int _data;
	int flag = 0;
	int flag2 = 0;

	int	i;
	int end = 0;

	int ss = 0;

	unsigned long addr;

	char	buf[100] = "";;

	while(1)
	{
		// 初期化
		for( ss = 0; ss < 100; ss++ ){
			buf[ss] = '\0';
		}

		getch();
		// ファイルを開く
		fp = fopen("a.txt", "rb");
		if(fp == NULL)
		{
			printf("ファイルがオープンできません.\n");        
			return;
		}
		// データの終わりまでロード
		for(addr = 0; end!=1; addr += 16)
		{
			printf("%08lX  ", addr);

			// 16進データ
			for(i = 0; i < 16; i++)
			{
				if( flag )
				{
					fseek(fp, -1, SEEK_CUR );
					flag = 0;
					flag2 = 1;
				}
				// 1バイト読み込み
				if((data = getc(fp) ) == EOF)
				{
					buf[i] = '\0';
					for(;i < 16; i++)
					{
						printf("   ");
					}
					printf("  %s\n", buf);
					fclose(fp);
					end=1;
					return;
				}

				// 2行目で2バイト文字の2バイト目を表示するとおかしくなるので
				// スペースを入れる
				if( flag2 )
				{
					buf[i] = ' ';
					flag2 = 0;
				}
				else if( data < 0x80 )
				{ 
					// 制御文字なら
					if( data < 0x20 )
					{ 
						buf[i]='.';	// .を代入 
					}         
					else			// 英数字なら
					{ 
						buf[i] = data;	// そのまま 
					}
				}
				// 0x80以上
				else
				{
					// 半角カナ
					if( (data>0x9F)&&(data<0xE0) )
					{ 
						buf[i] = data;	// そのまま
					}
					// 2バイト文字の1バイト目なら・・
					else
					{ 
						buf[i] = data;	// 1バイト目を代入
						//_ismbslead( data, fp );
						if( i == 15 )
						{
							if((_data = getc(fp)) == EOF)// 次のデータをロード(fpは1個動く)
							{
								buf[i] = '.';
							}else{
								buf[i+1] = _data;	// 
								flag = 1;
							}
						}
					}
				}
				printf("%02X ", data);
			}
			printf("  %s\n", buf);
		}
	}
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ダンププログラムについて教えてください

#10

投稿記事 by softya(ソフト屋) » 14年前

特殊な関数はありません。
全てiなどから判断するしかありませんが、この処理のままだとすごく条件がややこしくなることは間違いないでしょう(既にコードがややこしいです)。
あまり直したくないコードになるのでシンプルに書いたものを参考に提示しますのでお待ち下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かずま

Re: ダンププログラムについて教えてください

#11

投稿記事 by かずま » 14年前

入力ファイルのサイズが 16の倍数のとき、アドレスを余計に表示するバグがありますが、

コード:

#include <stdio.h>
#include <ctype.h>
 
int is_sjis1(unsigned char c) { return (c ^ 0x20) - 0xA1u < 60; }
int is_sjis2(unsigned char c) { return c >= 0x40 && c <= 0xfc && c != 0x7f; }

int get_c2(int c1, FILE *fp)
{
    int c2;
    if (!is_sjis1(c1) || (c2 = fgetc(fp)) == EOF) return 0;
    ungetc(c2, fp);
    return  is_sjis2(c2) ? c2 : 0;
}

void dump(FILE *fp)
{
    char buf[20];  int i, c1, c2 = 0;  long addr;

    for (addr = 0; ; addr += 16) {
        printf("%08X  ", addr);
        for (i = 0; i < 16; i++) {
            if ((c1 = fgetc(fp)) == EOF) {
                printf("%*s  %.*s\n", (16 - i) * 3, "", i, buf);
                return;
            }
            printf("%02X ", c1);
            if (c2)
                buf[i] = c2, c2 = 0;
            else
                buf[i] = ((c2 = get_c2(c1, fp)) || isprint(c1)) ? c1 : '.';
            if (c2 && i == 15)
                buf[16] = c2, c2 = ' ';
        }
        printf("  %.*s\n", c2 ? 17 : 16, buf);
    }
}

int main(void)
{
    FILE *fp = fopen("a.txt", "rb");
    if (fp == NULL) { 
        printf("ファイルがオープンできません.\n");
        return 1;
    }
    dump(fp);
    fclose(fp);
    return 0;
}

かずま

Re: ダンププログラムについて教えてください

#12

投稿記事 by かずま » 14年前

かずま さんが書きました:入力ファイルのサイズが 16の倍数のとき、アドレスを余計に表示するバグがありますが、
半角片仮名が出ないバグがありました。

int is_print(unsigned char c) { return isprint(c) || c >= 0xa1 && c <= 0xdf; }
を追加し、
buf = ((c2 = get_c2(c1, fp)) || isprint(c1)) ? c1 : '.';
の isprint を is_print に変更してください。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ダンププログラムについて教えてください

#13

投稿記事 by softya(ソフト屋) » 14年前

本当は全部書きなおすのは良くないと思うのですが色々あって原型が残っていません。
あと、このぐらい色々やらないとお望みの結果は得られないと言うことです。
※ かずまさんのより長いです。

コード:

#include <stdio.h>
#include <conio.h>
#include <mbctype.h>

//	16進数の表示。
void PrintHex(int addr,int offset,int data)
{
	//	EOFなら
	if( data == EOF ) {
		//	先頭でなければ空白で埋める
		if( offset > 0 ) {
			for(;offset < 16; offset++) {
				printf("   ");
			}
		}
	} else {
		//	先頭ならアドレスを表示
		if( offset==0 ) {
			printf("%08lX  ", addr);
		}
		//	16進の表示
		printf("%02X ", data);
	}

}

//	文字を得る(全角・半角)
int GetChar(int datas[],char *curText,FILE *fp)
{
	int codesize;
	int data;
	int i;
	//	最大2バイト
	for( i=0 ; i<2 ; i++ ) {
		//	文字コードのサイズ。
		codesize = i+1;
		//	1バイト読み込み。もしEOFなら
		if( (data = datas[i] = getc(fp) ) == EOF ) {
			//	これが2バイト目
			if( i == 1 ) {
				curText[i-1] = '.';	// 1つ前の文字は全角不成立で表示不可
			}
			curText[i] = '\0';//文字列終端
			//	EOFなのでここまで。
			break;
		} else {
			//	2バイト目なら
			if( i == 1 ) {
				//	2バイト目のコード
				curText[i] = data;//文字。2バイト目
			} else {
				//	全角文字判定
				if( ((0x81<=data)&&(data<=0x9F)) || ((0xE0<=data)&&(data<=0xFC)) ){
					//	全角の1バイト目のコード
					curText[i] = data;//文字。
				} else {
					//	半角文字コードで表示可能
					if( ((0x20<=data)&&(data<=0x7E)) || ((0xA1<=data)&&(data<=0xDF)) ){
						curText[i] = data;	// そのまま
					} else {
						curText[i] = '.';	// 表示不可
					}
					curText[i+1] = '\0';//文字列終端
					//	1バイト文字なのでここで終了。
					break;
				}
			}
			curText[i+1] = '\0';//文字列終端
		}
	}
	//	有効データ数を返す。
	return codesize;
}

//	テキストの表示。
void PrintText(char textbuf[])
{
	printf("  %s\n", textbuf);
}

int main()
{
	FILE *fp;
	int data,i,codesize,offset,fn;
	unsigned long addr;
	char textbuf[100] = "";
	int datas[2];
	char *curText = textbuf;
	char *fileNames[] = {
		"a.txt",
		"b.txt",
		"c.txt",
		"d.txt",
		NULL,
	};

	for( fn=0 ; fileNames[fn]!=NULL ; fn++ ) {
		//        getch();
		// ファイルを開く
		fp = fopen(fileNames[fn], "rb");
		if(fp == NULL)
		{
			printf("ファイルがオープンできません.\n");        
			return -1;
		}
		printf ("-- file=%s --\n",fileNames[fn]);
		
		// データの終わりまで処理
		data = 0;
		addr = 0;
		offset = 0;
		while( data!=EOF ) {
			//	文字を得る。
			codesize = GetChar(datas,textbuf+offset,fp);
			//	得られた文字サイズだけ処理
			for( i=0; i<codesize ; i++ ) {
				//	16進の表示
				PrintHex(addr,offset,datas[i]);
				//	最後の文字(EOFの情報)。
				if( EOF == (data=datas[i]) )  {
					break;//EOFなら抜ける
				}
				//	アドレスとオフセットの計算
				offset++;
				addr++;
				//	改行位置まで来ていたらテキストを表示
				if( offset >= 16 ) {
					offset -= 16;
					//	テキストの表示。
					PrintText(textbuf);
					//	行をまたがる2バイトコードなら
					if( (i==0)&&(codesize==2) ) {
						//	先頭の文字コードは表示不可とする。
						textbuf[0] = '.';
						textbuf[1] = '\0';
					} else {
						//	テキストバッファを先頭に
						textbuf[0] = '\0';
					}
				}
			}
		}
		//	残りの文字があるなら。
		if( offset > 0 ) {
			//	テキストの表示。
			PrintText(textbuf);
		}
		//	ファイルを閉じる。
		fclose(fp);
	}
	 getch();
}
実行結果

コード:

-- file=a.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C E4 89 BA 8B 4C 20 8B   阿鋳鵜得御下記 九
00000010  E3 20 8C C2 8D B9 8E 74 91 83 94 77 91 63 8D AA   . 個沙師巣背祖根
00000020  96 D1 8C C2 8D B9 8E 74 91 83 94 77 91 63 8D AA   毛個沙師巣背祖根
00000030  88 A2 92 92 89 4C 93 BE 8C E4 89 BA 8B 4C 8B E3   阿鋳鵜得御下記九
-- file=b.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C E4 89 BA 8B 4C B9 8B   阿鋳鵜得御下記ケ九
00000010  E3                                                .
-- file=c.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C E4                     阿鋳鵜得御
-- file=d.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C                        阿鋳鵜得.
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: ダンププログラムについて教えてください

#14

投稿記事 by ( ゚д゚ ) » 14年前

かずまさん、softya(ソフト屋)さんどうもありがとうございました。
参考にさせていただきます。

かずま

Re: ダンププログラムについて教えてください

#15

投稿記事 by かずま » 14年前

かずま さんが書きました:入力ファイルのサイズが 16の倍数のとき、アドレスを余計に表示するバグがありますが、
上記のバグの修正版です。

コード:

#include <stdio.h>
#include <ctype.h>
 
int is_sjis1(unsigned char c) { return (c ^ 0x20) - 0xA1u < 60; }
int is_sjis2(unsigned char c) { return c >= 0x40 && c <= 0xfc && c != 0x7f; }
int is_print(unsigned char c) { return isprint(c) || c >= 0xa1 && c <= 0xdf; }

int get_c2(int c1, FILE *fp)
{
    int c2;
    if (!is_sjis1(c1) || (c2 = fgetc(fp)) == EOF) return 0;
    ungetc(c2, fp);
    return is_sjis2(c2) ? c2 : 0;
}

void dump(FILE *fp)
{
    char buf[20];  int i, c1, c2 = 0;  long addr;

    for (addr = 0; ; addr += 16) {
        for (i = 0; i < 16; i++) {
            if ((c1 = fgetc(fp)) == EOF) {
                if (i) printf("%*s  %.*s\n", (16 - i) * 3, "", i, buf);
                return;
            }
            if (i == 0) printf("%08lX  ", addr);
            printf("%02X ", c1);
            if (c2)
                buf[i] = c2, c2 = 0;
            else
                buf[i] = (c2 = get_c2(c1, fp)) || is_print(c1) ? c1 : '.';
            if (c2 && i == 15)
                buf[16] = c2, c2 = '_';
        }
        printf("  %.*s\n", c2 ? 17 : 16, buf);
    }
}

int main(int argc, char *argv[])
{
    if (argc <= 1) dump(stdin);
    else {
        int i;
        for (i = 1; i < argc; i++) {
            FILE *fp = fopen(argv[i], "rb");
            if (!fp) return printf("can't open %s\n", argv[i]), 1;
            dump(fp);
            fclose(fp);
        }
    }
    return 0;
}
実行結果

コード:

00000000  88 A2 92 92 89 00 93 BE 8C E4 89 BA 8B 4C 8B E3   阿鋳..得御下記九
00000010  96 D1 8C C2 8D B9 8E 74 91 83 94 77 91 63 0D 0A   毛個沙師巣背祖..
ダンプするのはバイナリファイルですから、0 も含まれることがあるんですよね。
同じファイルの softya(ソフト屋)さんのプログラムの実行結果

コード:

-- file=a.txt --
00000000  88 A2 92 92 89 00 93 BE 8C E4 89 BA 8B 4C 8B E3   阿鋳
00000010  96 D1 8C C2 8D B9 8E 74 91 83 94 77 91 63 0D 0A   毛個沙師巣背祖..
ファイルがオープンできません.

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ダンププログラムについて教えてください

#16

投稿記事 by softya(ソフト屋) » 14年前

2バイト目の漢字コードチェックサボっちゃったのがマズかったですね。
まだバグがある可能性がある事をお断りしておきます。

コード:

#include <stdio.h>
#include <ctype.h>

//	16進数の表示。
void PrintHex(int addr,int offset,int data)
{
	//	EOFなら
	if( data == EOF ) {
		//	先頭でなければ空白で埋める
		if( offset > 0 ) {
			for(;offset < 16; offset++) {
				printf("   ");
			}
		}
	} else {
		//	先頭ならアドレスを表示
		if( offset==0 ) {
			printf("%08lX  ", addr);
		}
		//	16進の表示
		printf("%02X ", data);
	}
}

//	半角チェック
int is_hankaku(int data)
{
	return ((0x20<=data)&&(data<=0x7E)) || ((0xA1<=data)&&(data<=0xDF));
}

//	文字を得る(全角・半角)
int GetChar(int datas[],char *curText,FILE *fp)
{
	int codesize;
	int data;
	int i;
	//	最大2バイト
	for( i=0 ; i<2 ; i++ ) {
		//	文字コードのサイズ。
		codesize = i+1;
		//	1バイト読み込み。もしEOFなら
		if( (data = datas[i] = getc(fp) ) == EOF ) {
			//	これが2バイト目
			if( i == 1 ) {
				curText[i-1] = '.';	// 1つ前の文字は全角不成立で表示不可
			}
			curText[i] = '\0';//文字列終端
			//	EOFなのでここまで。
			break;
		} else {
			//	2バイト目なら
			if( i == 1 ) {
				//	2バイト目のコードが正しい?
				if( ((0x40<=data)&&(data<=0x7E)) || ((0x80<=data)&&(data<=0xFC)) ){
					curText[i] = data;//文字。2バイト目
				} else {
					curText[i-1] = '.';	// 1つ前の文字は全角不成立で表示不可
					//	半角文字コードで表示可能
					if( is_hankaku(data) ){
						curText[i] = data;	// そのまま
					} else {
						curText[i] = '.';	// 表示不可
					}
				}
			} else {
				//	全角文字判定
				if( ((0x81<=data)&&(data<=0x9F)) || ((0xE0<=data)&&(data<=0xFC)) ){
					//	全角の1バイト目のコード
					curText[i] = data;//文字。
				} else {
					//	半角文字コードで表示可能
					if( is_hankaku(data) ){
						curText[i] = data;	// そのまま
					} else {
						curText[i] = '.';	// 表示不可
					}
					curText[i+1] = '\0';//文字列終端
					//	1バイト文字なのでここで終了。
					break;
				}
			}
			curText[i+1] = '\0';//文字列終端
		}
	}
	//	有効データ数を返す。
	return codesize;
}

//	テキストの表示。
void PrintText(char textbuf[])
{
	printf("  %s\n", textbuf);
}

int main()
{
	FILE *fp;
	int data,i,codesize,offset,fn;
	unsigned long addr;
	char textbuf[100] = "";
	int datas[2];
	char *curText = textbuf;
	char *fileNames[] = {
		"a.txt",
		"b.txt",
		"c.txt",
		"d.txt",
		"e.txt",
		NULL,
	};

	for( fn=0 ; fileNames[fn]!=NULL ; fn++ ) {
		//        getch();
		// ファイルを開く
		fp = fopen(fileNames[fn], "rb");
		if(fp == NULL)
		{
			printf("ファイルがオープンできません.\n");        
			return -1;
		}
		printf ("-- file=%s --\n",fileNames[fn]);
		
		// データの終わりまで処理
		data = 0;
		addr = 0;
		offset = 0;
		while( data!=EOF ) {
			//	文字を得る。
			codesize = GetChar(datas,textbuf+offset,fp);
			//	得られた文字サイズだけ処理
			for( i=0; i<codesize ; i++ ) {
				//	16進の表示
				PrintHex(addr,offset,datas[i]);
				//	最後の文字(EOFの情報)。
				if( EOF == (data=datas[i]) )  {
					break;//EOFなら抜ける
				}
				//	アドレスとオフセットの計算
				offset++;
				addr++;
				//	改行位置まで来ていたらテキストを表示
				if( offset >= 16 ) {
					offset -= 16;
					//	テキストの表示。
					PrintText(textbuf);
					//	行をまたがる2バイトコードなら
					if( (i==0)&&(codesize==2) ) {
						//	先頭の文字コードは表示不可とする。
						textbuf[0] = '.';
						textbuf[1] = '\0';
					} else {
						//	テキストバッファを先頭に
						textbuf[0] = '\0';
					}
				}
			}
		}
		//	残りの文字があるなら。
		if( offset > 0 ) {
			//	テキストの表示。
			PrintText(textbuf);
		}
		//	ファイルを閉じる。
		fclose(fp);
	}
	 getch();
}

コード:

-- file=a.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C E4 89 BA 8B 4C 00 8B   阿鋳鵜得御下記.九
00000010  E3 20 8C C2 8D B9 8E 74 91 83 94 77 91 63 8D AA   . 個沙師巣背祖根
00000020  96 D1 8C C2 8D B9 8E 74 91 83 94 77 91 63 8D AA   毛個沙師巣背祖根
00000030  88 A2 92 92 89 4C 93 BE 8C E4 89 BA 8B 4C 8B E3   阿鋳鵜得御下記九
-- file=b.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C E4 89 BA 8B 4C B9 8B   阿鋳鵜得御下記ケ九
00000010  E3                                                .
-- file=c.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C E4                     阿鋳鵜得御
-- file=d.txt --
00000000  88 A2 92 92 89 4C 93 BE 8C                        阿鋳鵜得.
-- file=e.txt --
00000000  88 A2 92 92 89 00 93 BE 8C E4 89 BA 8B 4C 8B E3   阿鋳..得御下記九
00000010  96 D1 8C C2 8D B9 8E 74 91 83 94 77 91 63 0D 0A   毛個沙師巣背祖..
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る