このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

ファイルの16進ダンプ

最初の頃の課題:装飾はなくていいので、とにかく16進でダンプ。

素直に無駄なく、必要なことだけをストレートに書く。そして、次のようなしきたりは守る。

  1. 引数なしならstdin(標準入力)、これは絶対ってわけでもない。
  2. エラーメッセージはstderrに! これは絶対。
  3. 成功なら0、失敗なら0以外の終了ステータス、これも絶対。コマンドラインシェルスクリプトでは、なぜか0がtrue。


#include

#define DELM_CH ','
#define SIZE_OF_BLOCK 16

#define OK 0
#define CANT_OPEN (-1)

typedef unsigned char byte;

print_byte_in_hex(byte b)
{
static int hex[] = {'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'c', 'D', 'E', 'F' };
putchar(hex[b>>4]);
putchar(hex[b&0xF]);
}

print_block_in_hex(byte *block, int size)
{
int i;
for (i = 0; i < size; i++) {
print_byte_in_hex(block[i]);
if (i < size - 1) putchar(DELM_CH);
}
putchar('\n');
}

dump_file(FILE *fp)
{
byte buffer[SIZE_OF_BLOCK];
size_t n_bytes;
while (n_bytes = fread(buffer, 1, SIZE_OF_BLOCK, fp)) {
print_block_in_hex(buffer, n_bytes);
}
}

open_and_dump_file(char *filename)
{
FILE *fp = fopen(filename, "rb");
if (fp == NULL) return CANT_OPEN;
dump_file(fp);
fclose(fp);
return OK;
}

main(int argc, char **argv)
{
if (argc == 1) {
dump_file(stdin);
} else if (open_and_dump_file(argv[1]) == CANT_OPEN) {
fprintf(stderr, "can not open file '%s'\n", argv[1]);
exit(1);
}
exit(0);
}

  1. 関数の数はやや多いが、どの関数も10行以内
  2. 入れ子はあっても一段階まで
  3. 個々の関数は再利用可能(ライブラリにできる)。
  4. define定数を書き換えて若干のカスタマイズ可能。