質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.34%

C言語 ダンプ出力したい

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 3,718

score 109

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable: 4996)

#define H_PRT 0x02// ヘッダ印字オプション 
#define C_PRT 0x01// 文字印字オプション
#define ROW 16 // 1行に表示する文字
#define TESTBUF 512 //テストデータ用のバッファ
#define TEXTBUF 16 //テキストファイル用のバッファ

//プロトタイプ宣言
void dump(char* title, unsigned char* staddr, int offset, int dsize, char opt);

void main(void) {

    //int filcnt;// フィル用のカウンタ

    //char bin_data[TESTBUF];// テストデータ用のバッファ
    //char asc_data[] = "01234567809 ABCあいうえおかきくけこDEFGHIJKLMNOPQRSTUVWXYZ 漢字表示のテスト abcdefghijklmnopqrstuvwxyz01234567809ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz";
    char txt_data[TEXTBUF]; // テキストファイル読み込み用
    //char txt;
    int readnum;

    FILE* file;
    file = fopen("s-jis2.txt", "rb");
    if (file == NULL) {
        printf("ファイルが開けません");
        exit(1);
    }

    while (readnum = fread(txt_data, sizeof(unsigned char), TEXTBUF, file) > 0) {

        dump("テキストファイル", txt_data, 0, TEXTBUF, C_PRT + H_PRT);
    }
    fclose(file);
}

void dump(char* title, unsigned char* staddr, int offset, int dsize, char opt) {

    static int startcnt = 0;// ダンプするバイト数のカウント
    int bytecnt; // 16回ループさせる
    static int savecnt;
    static int address = 0; //アドレスの表示
    static int onhold = 0; //文字出力が最後のバイトだった時の一時保留
    staddr += offset;
    static int headercnt = 0;

    char addrhead[] = "Addr";
    char hexa[] = "0 1  2 3  4 5  6 7  8 9  A B  C D  E F";
    char charprint[] = "0 2 4 6 8 A C E";

    while (startcnt < dsize) {

        if (onhold != 0) {  //前回最後が漢字だった場合、漢字を出力して改行

            printf("%c%c\n", onhold, staddr[startcnt]);
        }

        //初回ヘッダー表示 opt & H_PRT == 0だった時は16行毎にヘッダー表示
        if ((headercnt == 0) || ((opt & H_PRT) == 0) && (headercnt % ROW == 0)) {
            //16行毎にヘッダー
            printf("\n%s\n", title);
            printf("  %s     %s  ", addrhead, hexa);


            if ((opt & C_PRT) != 0) {  //opt が文字表示の場合 文字ヘッダー表示

                printf("%s", charprint);
            }

            printf("\n");
            printf("--------  ---- ---- ---- ---- ---- ---- ---- ----");

            if ((opt & C_PRT) != 0) { ////opt が文字表示の場合 文字罫線表示
                printf("  ----------------");

            }
            printf("\n");
        }

        headercnt++;

        printf("%08x  ", address);

        savecnt = startcnt;
        for (bytecnt = 0; bytecnt < ROW; bytecnt++) {

            if (startcnt < dsize) {
                printf("%02x", staddr[startcnt]); //16進数で出力
            }
            else {
                printf("  ");
            }
            if (startcnt % 2 != 0) {
                printf(" ");
            }
            startcnt++;
        }

        //文字の出力

        if ((opt & C_PRT) != 0) {   //optで文字表示の場合 表示

            startcnt = savecnt;
            printf(" ");

            for (bytecnt = 0; bytecnt < ROW; bytecnt++) {

                if (onhold != 0) {  //前回最後が漢字だった場合 次の行の最初にスペースと初期化

                    printf(" ");
                    onhold = 0;
                    bytecnt++;
                    startcnt++;
                }

                if (startcnt < dsize) {

                    //漢字だった場合
                    if ((staddr[startcnt] >= 0x81 && staddr[startcnt] < 0xa0) || (staddr[startcnt] >= 0xe0 && staddr[startcnt] < 0xfd)) {

                        if (bytecnt < ROW - 1) {  //最後のバイトでなければ

                            printf("%c%c", staddr[startcnt], staddr[startcnt + 1]);
                            startcnt++;
                            bytecnt++;
                        }
                        else {//漢字で最後のバイトの場合、保留

                            onhold = staddr[startcnt];
                        }
                    }
                    else {

                        if ((staddr[startcnt] >= 0x20 && staddr[startcnt] < 0x7f) || (staddr[startcnt] >= 0xa0 && staddr[startcnt] < 0xe0)) {

                            printf("%c", staddr[startcnt]);
                        }
                        else {
                            printf("");
                        }
                    }
                }
                else {
                    printf(" ");
                }

                startcnt++;
            }
            if (onhold == 0) {  //最後が漢字でなければ改行
                printf("\n");
            }
        }
        else {  //optが文字表示ではない場合 改行

            printf("\n");
        }
        address += ROW; //addressを出力しただけ足す
    }
}

下記のコードで16文字ずつ textdata の中を読み込みたいのですが

テキストファイル
Addr     0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0 2 4 6 8 A C E
--------  ---- ---- ---- ---- ---- ---- ---- ----  ----------------
00000000  8e84 82bd 82bf 4a54 4543 2043 6f72 706f  私たちああああ Corpo

一行出力して終わってしまいます。
アドバイス頂けると助かります。

コード

while (readnum = fread(txt_data, sizeof(unsigned char), TEXTBUF, file) > 0) {

        dump("テキストファイル", txt_data, 0, TEXTBUF, C_PRT + H_PRT);
    }
    fclose(file);
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

Cのコードを書くなら、VisualStudioとかEclipseなどのデバッグできる環境を整えましょう。
ソースコードの任意の行で実行を止め、変数の値を見ることができます。
また、1行づつ実行することもできます。
そうすれば、あてずっぽでコードを書かなくて済むようになり、こんなところで何度も質問を書かなくてもいいようになります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

static int startcnt = 0;// ダンプするバイト数のカウント

static の意味を考えてください。
なぜ、stataic を付けたんですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/08 19:17

    staticいらないですね。

    キャンセル

  • 2019/08/08 19:55

    なぜ、stataic を付けたんですか?
    何がしたいんですか?

    キャンセル

0

ほとんど、答えは出てますが、

 static int startcnt = 0;// ダンプするバイト数のカウント

ここの初期化は、最初のみなので、二回目以降に呼ばれた時に前の値。
次の行に、startcnt = 0; でも良いですが、まあ、普通には、static削除が一般的でしょう。
他のも不要なのがありますね。 savecntも不要。headercntも無しで済みそうですが、要確認か?
あと、壊れた漢字対策とか、最後のバイトが漢字前半の場合の位置ずれとか、ちょっと気になりますが、とりあえず、保留。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/09 10:51

    address, onholdのみstaticでした。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る