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

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

ただいまの
回答率

90.50%

  • C

    4523questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

漢字が正しく表示されない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 842

hinatti

score 6

前提・実現したいこと

ファイルダンププログラムを作成しているのですが、漢字が正しく表示できないです。

発生している問題・エラーメッセージ

一部が文字化けしてしまう

該当のソースコード

typedef struct _DumpData{
    unsigned char fileName[MAX];       //ファイル名
    unsigned char data[MAX];         //読み込んだデータ
    long size;                         //ファイル容量
    int contents;                      //freadの戻り値
    int blockSize;                     //ブロックサイズ
    int totalBlock;                    //総ブロック数
    FILE* file_pointer;                //ファイルポインタ
    int format;                        //表示フォーマット
    int chinese_characters;            //漢字表示
    int blockNumber;                   //現在のブロック番号
    unsigned char errorField[40];      //エラー表示フィールド
} DumpData;

//↑構造体です。
void file_display_one(DumpData* pointer)
{
    unsigned char key;
    int output;//出力桁数
    int hex = 0;//16進数カウンタ
    int asc = 0;//文字カウンタ
    int line_number;//行番号
    short character_flag = 0;//文字フラグ

    printf(" Addr   Hex                                             ASCII\n");

    //選択したブロックサイズ÷16した数が行番号より大きい間繰り返し
    line_number = 0;
    while ((pointer->blockSize / DISPLAY_MAX_ONE) > line_number)
    {
        //行番号の表示
        printf(" %05X  ", line_number);

        //16個出力するまでループ
        for (output = 0; DISPLAY_MAX_ONE > output; output++)
        {
            //freadの戻り値が出力数より大きいとき
            if (pointer->contents > hex)
            {
                //8個目と9個目の間に"-"表示
                if (output == 7)
                {
                    printf("%02X-", pointer->data[hex]);
                }
                else
                {
                    printf("%02X ", pointer->data[hex]);
                }

                hex++;
            }
            else
            {
                printf("   ");
            }
        }

        //16文字出力するまでループ
        for (output = 0; DISPLAY_MAX_ONE > output; output++)
        {
            //freadの戻り値が出力数より大きいとき
            if (pointer->contents > asc)
            {
                key = pointer->data[asc];

                //漢字表示ONの時(SHIFT-JIS)
                if (pointer->chinese_characters == 1)
                {
                    //全角文字の1byte目の時
                    if ((key >= 0x81 && key <= 0x9f) || (key >= 0xe0 && key <= 0xfc))
                    {
                        //出力文字数が16の時
                        if (output == 15)
                        {
                            putchar('$');
                            character_flag = RET_OK;//文字フラグを1にする
                        }
                        else
                        {
                            putchar(key);
                        }
                    }
                    else
                    {
                        //文字フラグが1の時
                        if (character_flag == RET_OK)
                        {
                            putchar('$');
                            character_flag = 0;//文字フラグを0にする
                        }
                        //半角文字の時
                        else if ((key >= 0x20) && (key <= 0x7e))
                        {
                            putchar(key);
                        }
                        //全角文字、半角文字でもない場合
                        else
                        {
                            putchar('$');
                        }
                    }
                }
                //漢字表示OFFの時(ASCII)
                else
                {
                    //半角文字の時
                    if ((key >= 0x20) && (key <= 0x7e))
                    {
                        putchar(key);
                    }
                    else
                    {
                        putchar('$');
                    }
                }

                asc++;
            }
            else
            {
                putchar(' ');
            }
        }

        line_number++;//行番号のカウントアップ
        printf("\n");

        //4行出力ごとに改行
        if ((line_number % 4) == 0)
        {
            printf("\n");
        }
    }
}

試したこと

ファイルの内容を配列に格納して配列の先頭から1バイトずつ判断しようとしてみました。あと、printfの%sも試したのですがプログラムが終了しちゃいます。

補足情報(言語/FW/ツール等のバージョンなど)

サクラエディタ、SDKコマンドプロンプトで開発しています。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • showkit

    2017/08/07 17:07

     大体の想像はつくような気がしますが・・・。Q1. DumpData とは どんな型ですか? Q2. 入力ファイルはテキストファイルですか?

    キャンセル

  • hinatti

    2017/08/07 17:09

    DumpDateは構造体で、入力ファイルはテキストファイルです。

    キャンセル

  • showkit

    2017/08/07 17:15

    不勉強でわかっていなかったらごめんなさい。DumpData という汎用の型があるのですか?汎用でなければ DumpData 構造体の定義も 提示していただかないと・・・。

    キャンセル

  • hinatti

    2017/08/07 17:16

    今提示しました。

    キャンセル

回答 2

checkベストアンサー

+2

ご提示PGに少しだけ手を加えてみました。SJIS用ですが。

void file_display_one(DumpData* pointer)
{
    unsigned char key;
    int output;//出力桁数
    int hex = 0;//16進数カウンタ
    int asc = 0;//文字カウンタ
    int line_number;//行番号
    short character_flag = 0;//文字フラグ
    short character_zen = 0;//文字フラグ

    printf(" Addr   Hex                                             ASCII\n");

    //選択したブロックサイズ÷16した数が行番号より大きい間繰り返し
    line_number = 0;
    while ((pointer->blockSize / DISPLAY_MAX_ONE) > line_number)
    {
        //行番号の表示
        printf(" %05X  ", line_number);

        //16個出力するまでループ
        for (output = 0; DISPLAY_MAX_ONE > output; output++)
        {
            //freadの戻り値が出力数より大きいとき
            if (pointer->contents > hex)
            {
                //8個目と9個目の間に"-"表示
                if (output == 7)
                {
                    printf("%02X-", pointer->data[hex]);
                }
                else
                {
                    printf("%02X ", pointer->data[hex]);
                }

                hex++;
            }
            else
            {
                printf("   ");
            }
        }

        //16文字出力するまでループ
        for (output = 0; DISPLAY_MAX_ONE > output; output++)
        {
            //freadの戻り値が出力数より大きいとき
            if (pointer->contents > asc)
            {
                key = pointer->data[asc];

                //漢字表示ONの時(SHIFT-JIS)
                if (pointer->chinese_characters == 1)
                {
                    //全角文字の2byte目の時
                    if (character_zen == RET_OK)
                    {
                        putchar(key);
                        character_zen = 0;//文字フラグを0にする
                    }
                    //文字フラグが1の時
                    else if (character_flag == RET_OK)
                    {
                        putchar('$');
                        character_flag = 0;//文字フラグを0にする
                    }
                    //全角文字の1byte目の時
                    else if ((key >= 0x81 && key <= 0x9f) || (key >= 0xe0 && key <= 0xfc))
                    {
                        //出力文字数が16の時
                        if (output == 15)
                        {
                            putchar('$');
                            character_flag = RET_OK;//文字フラグを1にする
                        }
                        else
                        {
                            putchar(key);
                            character_zen = RET_OK;//文字フラグを1にする
                        }
                    }
                    else
                    {
                        //半角文字の時
                        if ((key >= 0x20) && (key <= 0x7e))
                        {
                            putchar(key);
                        }
                        //半角カナ文字の時
                        else if ((key >= 0xa1) && (key <= 0xdf))
                        {
                            putchar(key);
                        }
                        //全角文字、半角文字でもない場合
                        else
                        {
                            putchar('$');
                        }
                    }
                }
                //漢字表示OFFの時(ASCII)
                else
                {
                    //半角文字の時
                    if ((key >= 0x20) && (key <= 0x7e))
                    {
                        putchar(key);
                    }
                    else
                    {
                        putchar('$');
                    }
                }

                asc++;
            }
            else
            {
                putchar(' ');
            }
        }

        line_number++;//行番号のカウントアップ
        printf("\n");

        //4行出力ごとに改行
        if ((line_number % 4) == 0)
        {
            printf("\n");
        }
    }
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/08/08 14:54

    おぉ…!ありがとうございます…!
    いけそうなんですけどこのプログラムを参考にさせていただいて組み込んでみたのですが何故か所々変な改行が入ってしまいます…

    キャンセル

  • 2017/08/08 15:01

    すみません、マルチバイト文字の2バイト目のフラグを文字フラグと間違えたのが原因でしたw
    おかげさまで完成しました、本当にありがとうございました!

    キャンセル

0

まずどの文字コードを想定していますかね?UTF-8ならこれではだめです(1byte-4byte使うため)。また1byte目のときもputcharで出力しているようですがこれが原因では?1文字を表す最後の単位数のときにまとめてprintfかなにかで出力しましょう。

printfの%sも試したのですがプログラムが終了しちゃいます。

文字列はNULL終端されていますか?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/08/07 18:22

    あ、shift-jisを想定しています。
    %c%cみたいにですかね
    あ、してなかったです…

    キャンセル

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

  • C

    4523questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。