LoginSignup
1
2

More than 3 years have passed since last update.

C言語 hexdump風に文字列を出力するプログラム

Last updated at Posted at 2020-12-02

オリジナルhexdump関数

メモリ領域を表示する関数です。
以下の3つの要素からなります。

  • アドレス部
  • ASCII部
  • 文字列部

文字が表示文字でない場合は'.'に置き換えます。

コード

#include <stdint.h>
#include <unistd.h>
#define PRINTABLE(a) (' ' <= a && a <= '~')

void ft_print_nbr(uintmax_t n)
{
    char buf[17];
    char *p;

    p = buf;
    *p++ = '\0';
    while (1)
    {
        *p = "0123456789abcdef"[(n % 16)];
        n /= 16;
        if (!n)
            break ;
        p++;
    }
    if (!*(p - 1))
        *++p = '0';
    if (*(p - 2))
        for (int i = 0; i < 7; i++)
            *++p = '0';
    while(*p)
        write(1, p--, 1);
}

void *ft_print_memory(void *addr)
{
    unsigned char *s1;
    unsigned char *s2;

    if (!addr)
        return NULL;
    s1 = (unsigned char *)addr;
    s2 = s1;
    while (*s1)
    {
        ft_print_nbr((uintmax_t)s1);
        write(1, ": ", 2);
        for (int i = 0; i < 16; i++)
        {
            *s1 ? ft_print_nbr(*s1++) : write(1, "  ", 2);
            if (i % 2)
                write(1, " ", 1);
        }
        for (int i = 0; i < 16; i++)
            if (*s2)
            {
                write(1, (PRINTABLE(*s2) ? s2 : (unsigned char *)".") , 1);
                s2++;
            }
        write(1, "\n", 1);
    }
    return addr;
}

int main()
{
    char *s = "To find information use the search box on the top right corner of the screen, or categorically browse the wiki using the Documentation topic links provided below.";
    ft_print_memory(s);
    return 0;
}

出力結果

0000000100003f11: 546f 2066 696e 6420 696e 666f 726d 6174 To find informat
0000000100003f21: 696f 6e20 7573 6520 7468 6520 7365 6172 ion use the sear
0000000100003f31: 6368 2062 6f78 206f 6e20 7468 6520 746f ch box on the to
0000000100003f41: 7020 7269 6768 7420 636f 726e 6572 206f p right corner o
0000000100003f51: 6620 7468 6520 7363 7265 656e 2c20 6f72 f the screen, or
0000000100003f61: 2063 6174 6567 6f72 6963 616c 6c79 2062  categorically b
0000000100003f71: 726f 7773 6520 7468 6520 7769 6b69 2075 rowse the wiki u
0000000100003f81: 7369 6e67 2074 6865 2044 6f63 756d 656e sing the Documen
0000000100003f91: 7461 7469 6f6e 2074 6f70 6963 206c 696e tation topic lin
0000000100003fa1: 6b73 2070 726f 7669 6465 6420 6265 6c6f ks provided belo
0000000100003fb1: 772e                                    w.

ポイント

  • アドレスも数字なので、アドレス部とASCII部の出力を1つの関数にまとめました。
  • unsigned charにキャストすることで、拡張ASCIIに対応できるようにしています。
    • 文字を扱うときは、基本的にcharで渡されたとしても、unsigned charにキャストして使うのがおすすめです。
1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2