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

int main(int argc, char *argv[])
{
    FILE *fp_in;
    FILE *fp_out;

    unsigned char buf;
    unsigned long address;
    unsigned long filesize;
    int count = 0;

    /* 引数チェック */
    if (argc != 4)
    {
        printf("使用方法:\n");
        printf("%s <入力ファイル名> <先頭からの位置(バイト数)> <出力ファイル名>\n", argv[0]);
        return 1;
    }

    /* 入力ファイルを開く */
    fp_in = fopen(argv[1], "rb");
    if (fp_in == NULL)
    {
        printf("入力ファイルを開けません。\n");
        return 1;
    }

    /* 出力ファイルを開く */
    fp_out = fopen(argv[3], "w");
    if (fp_out == NULL)
    {
        printf("出力ファイルを開けません。\n");
        fclose(fp_in);
        return 1;
    }

    /* ファイルサイズ取得 */
    fseek(fp_in, 0, SEEK_END);
    filesize = ftell(fp_in);
    rewind(fp_in);

    /* ファイル名とサイズ表示 */
    printf("ファイル名: %s\n", argv[1]);
    printf("ファイルの大きさ: %lu Byte\n", filesize);

    fprintf(fp_out, "ファイル名: %s\n", argv[1]);
    fprintf(fp_out, "ファイルの大きさ: %lu Byte\n", filesize);

    /* 開始アドレス取得 */
    address = atol(argv[2]);

    /* 指定位置へ移動 */
    if (fseek(fp_in, address, SEEK_SET) != 0)
    {
        printf("シークエラー\n");

        fclose(fp_in);
        fclose(fp_out);

        return 1;
    }

    /* バイナリ表示 */
    while (fread(&buf, 1, 1, fp_in) == 1)
    {
        /* 8バイトごとにアドレス表示 */
        if (count % 8 == 0)
        {
            if (count != 0)
            {
                printf("\n");
                fprintf(fp_out, "\n");
            }

            printf("%08lX: ", address);
            fprintf(fp_out, "%08lX: ", address);
        }

        /* 16進数表示 */
        printf("%02X ", buf);
        fprintf(fp_out, "%02X ", buf);

        count++;
        address++;

    }

    printf("\n");
    fprintf(fp_out, "\n");

    /* ファイルを閉じる */
    fclose(fp_in);
    fclose(fp_out);

    return 0;
}
