项目开发中常用的十六进制方式打印实现

在项目开发中,比如网络开发,多媒体播放开发等,常常用到将接受数据和发送数据或者需要解析的数据,用打印方式呈现。方便自己定位问题。

在这个时候,printf难免没有满足我们的需要了。因为printf("bufdata =%s\n",bufdata),是用字符串方式输出,当碰到字符串中存在'\0'的时候,就会停止输出,造成打印不全,甚至打印死机(当字符串中没有'\0'结束符的时候,就会出现非法数据访问,造成死机)。下面介绍一种通用的16进制打印方式。简单易用。

/*
* 十六进制方式打印
* 应用场合:1)打印抓回来的网络包数据 
*			2)打印多媒体码流数据
*/
#include <stdio.h>
//十六进制和ASCII码打印
extern int func_hex_printout(const char* tag , const char* buf ,unsigned int  len ,  int  wide);

//十六进制打印
extern int func_hex_printout2(const char* tag , const char* buf ,unsigned int  len ,  int  wide);

//ASCII码打印
extern int func_hex_printout3(const char* tag , const char* buf ,unsigned int  len ,  int  wide);

#define HEX_INFO(tag , buf , buf_len) func_hex_printout(tag , buf , buf_len ,16)  
#define HEX_INFO2(tag , buf , buf_len) func_hex_printout2(tag , buf , buf_len ,16)  
#define HEX_INFO3(tag , buf , buf_len) func_hex_printout3(tag , buf , buf_len ,16)  

int main(int argc ,char *argv[])
{

	char TAG[] = "DEBUG";
	char buf[128] = "abcdefghijklmnopqrstuvwxyz\n\r\0\t123456789";
	int len = sizeof(buf);
	HEX_INFO(TAG , buf , len);
	HEX_INFO2(TAG , buf , len);
	HEX_INFO3(TAG , buf , len);
	return 0;
}

/*重定义符合目前操作系统显示的打印函数*/
#define INFO_PRINT printf

/*
*函数功能:十六进制和ASCII码打印
*参数:tag 打印标签
	   buf 数据
	   len 数据buf长度
	   wide 字宽
*/
int func_hex_printout(const char* tag , const char* buf ,unsigned int  len ,  int  wide)
{

    int i = 0 ;
    int ret     = 0;
    int nTabs   = 0;
    int nlines  = 0;
    char msgbuf[128] = {0};
    const char hex_char[] = "0123456789ABCDEF";
    const unsigned char *ptr = (const unsigned char*)buf;
    if ((NULL == tag) || (NULL == buf) || ((8 != wide) && (16 != wide)))
    {
        return ret;
    }
	//打印buf的内存地址和输出打印的长度。
    INFO_PRINT("%s buf addr=%08lx, buf len=%ld bytes\n", tag, buf, len);
    /* calculate how many prefixing Tab */
    while ((*tag == '\r') || (*tag == '\n'))
    {
        tag++;              // skip prefixing '\r' or '\n'
    }
    while (*tag++ == '\t')
    {
        nTabs++;
        if (6 == nTabs)
        {
            break;
        }
    }
    if (8 == wide)
    {
        nlines = (len + 0x07) >> 3;
    }
    else if (16 == wide)
    {
        nlines = (len + 0x0f) >> 4;
    }

    for (i = 0; i < nlines; i++)
    {
        int j = 0;
        char *dst  = msgbuf;
        int nbytes = ((int)len < wide) ? len : wide;
        for (j = 0; j < nTabs; j++)
        {
            *dst++ = '\t';
        }
        *dst++ = ' ';
        *dst++ = ' ';
        *dst++ = ' ';
        *dst++ = ' ';
        for (j = 0; j < nbytes; j++)
        {
            unsigned char ival = *ptr++;
            //一个char型变量用16进制输出,然后再输出一个空格,共占用三个字符空间
            *dst++ = hex_char[(ival >> 4) & 0x0F];
            *dst++ = hex_char[ival & 0x0F];
            *dst++ = ' ';
        }
        //输出一行数值后,输出三个空格,再输出该行数值的ASCII码字符
        //若nbytes小于一行的长度,即小于8或16,则以三个空格代替一个数值输出
        for (j = 0; j < wide - nbytes + 1; j++)
        {
            *dst++ = ' ';
            *dst++ = ' ';
            *dst++ = ' ';
        }
        ptr -= nbytes;
        for (j = 0; j < nbytes; j++)
        {
            if ((*ptr >= 0x20) && (*ptr <= 0x7e))
            {
                *dst = *ptr;
            }
            else
            {
                *dst = '.';
            }
            ptr++;
            dst++;
        }
        *dst = 0;
        ret += INFO_PRINT("%s\n", msgbuf);
        len -= nbytes;
    }
    return ret;
}

/*
*函数功能:十六进制打印
*参数:tag 打印标签
	   buf 数据
	   len 数据buf长度
	   wide 字宽
*/
int func_hex_printout2(const char* tag , const char* buf ,unsigned int  len ,  int  wide)
{

    int i = 0 ;
    int ret     = 0;
    int nTabs   = 0;
    int nlines  = 0;
    char msgbuf[128] = {0};
    const char hex_char[] = "0123456789ABCDEF";
    const unsigned char *ptr = (const unsigned char*)buf;
    if ((NULL == tag) || (NULL == buf) || ((8 != wide) && (16 != wide)))
    {
        return ret;
    }
	//打印buf的内存地址和输出打印的长度。
    INFO_PRINT("%s buf addr=%08lx, buf len=%ld bytes\n", tag, buf, len);
    /* calculate how many prefixing Tab */
    while ((*tag == '\r') || (*tag == '\n'))
    {
        tag++;              // skip prefixing '\r' or '\n'
    }
    while (*tag++ == '\t')
    {
        nTabs++;
        if (6 == nTabs)
        {
            break;
        }
    }
    if (8 == wide)
    {
        nlines = (len + 0x07) >> 3;
    }
    else if (16 == wide)
    {
        nlines = (len + 0x0f) >> 4;
    }

    for (i = 0; i < nlines; i++)
    {
        int j = 0;
        char *dst  = msgbuf;
        int nbytes = ((int)len < wide) ? len : wide;
        for (j = 0; j < nTabs; j++)
        {
            *dst++ = '\t';
        }
        *dst++ = ' ';
        *dst++ = ' ';
        *dst++ = ' ';
        *dst++ = ' ';
        for (j = 0; j < nbytes; j++)
        {
            unsigned char ival = *ptr++;
            //一个char型变量用16进制输出,然后再输出一个空格,共占用三个字符空间
            *dst++ = hex_char[(ival >> 4) & 0x0F];
            *dst++ = hex_char[ival & 0x0F];
            *dst++ = ' ';
        }
        *dst = 0;
        ret += INFO_PRINT("%s\n", msgbuf);
        len -= nbytes;
    }
    return ret;
}

/*
*函数功能:ASCII码打印
*参数:tag 打印标签
	   buf 数据
	   len 数据buf长度
	   wide 字宽
*/
int func_hex_printout3(const char* tag , const char* buf ,unsigned int  len ,  int  wide)
{

    int i = 0 ;
    int ret     = 0;
    int nTabs   = 0;
    int nlines  = 0;
    char msgbuf[128] = {0};
    const char hex_char[] = "0123456789ABCDEF";
    const unsigned char *ptr = (const unsigned char*)buf;
    if ((NULL == tag) || (NULL == buf) || ((8 != wide) && (16 != wide)))
    {
        return ret;
    }
	//打印buf的内存地址和输出打印的长度。
    INFO_PRINT("%s buf addr=%08lx, buf len=%ld bytes\n", tag, buf, len);
    /* calculate how many prefixing Tab */
    while ((*tag == '\r') || (*tag == '\n'))
    {
        tag++;              // skip prefixing '\r' or '\n'
    }
    while (*tag++ == '\t')
    {
        nTabs++;
        if (6 == nTabs)
        {
            break;
        }
    }
    if (8 == wide)
    {
        nlines = (len + 0x07) >> 3;
    }
    else if (16 == wide)
    {
        nlines = (len + 0x0f) >> 4;
    }

    for (i = 0; i < nlines; i++)
    {
        int j = 0;
        char *dst  = msgbuf;
        int nbytes = ((int)len < wide) ? len : wide;
        for (j = 0; j < nTabs; j++)
        {
            *dst++ = '\t';
        }
        *dst++ = ' ';
        *dst++ = ' ';
        *dst++ = ' ';
        *dst++ = ' ';
        for (j = 0; j < nbytes; j++)
        {
            if ((*ptr >= 0x20) && (*ptr <= 0x7e))
            {
                *dst = *ptr;
            }
            else
            {
                *dst = '.';
            }
            ptr++;
            dst++;
        }
        *dst = 0;
        ret += INFO_PRINT("%s\n", msgbuf);
        len -= nbytes;
    }
    return ret;
}

PC终端运行效果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值