C++编写二进制字符数组转ASCII码的函数

原文链接:http://blog.csdn.net/gzliudan/article/details/23478169

    在工控通信中经常用到16进制和ASCII码字符数组互相转换的功能,虽然功能简单,但初学者写出来的代码经常会有各种问题。从16进制转为ASCII吗的功能函数,一个比较简洁的实现版本如下:

void HexToAscii( char * Dest, char * Src, int SrcLen )
{
    for ( int i = 0, j = 0; i < SrcLen; i++ )
    {
         char HiHalf = Src[i] >> 4;
         char LoHalf = Src[i] & 0x0F;
         Dest[j++] = ( HiHalf <= 9 ) ? ( HiHalf + '0' ) : ( HiHalf - 10 + 'A' );
         Dest[j++] = ( LoHalf <= 9 ) ? ( LoHalf + '0' ) : ( LoHalf - 10 + 'A' );
    }
}


    在以上短短几行代码里,基础比较扎实的同学比较容易发现的一个Bug是用signed char来处理二进制数据,这样当被处理的字节Src[i]是负数时就会出现错误的转换结果。同样把HiHalf和LoHalf声明为int,也是有相同Bug的。解决办法是先把Src[i]转为unsigned char,并且把HiHalf和LoHalf定义为unsigned char。

    一个比较隐蔽的严重问题是当Dest和Src字符数组有重叠的地址空间时,转换结果也会不对。例如Dest和Src的地址相等时,Src[0]转换为Dest[0]和Dest[1]后,Src[1]被Dest[1]覆盖,Src[1]还没转换里面的数据已经不是原来的数据了,依次类推。

    除此以外,传进来的指针Dest和Src都要先判断是否等于NULL,这样才能尽量保证写出安全的代码。

   最后一点,最好把Dest和Src声明为void *类型的指针,这样对非char类型的数据调用此函数时,就不需要强制转化。

   修正后的代码如下:

void HexToAscii( void * DestBuf, void * SrcBuf, int SrcLen )
{
    if ( ( DestBuf == NULL ) || ( SrcBuf == NULL ) )
    {
    return;
    }

    unsigned char * Dest = (unsigned char *) DestBuf;
    unsigned char * Src = (unsigned char *) SrcBuf;
    int DestPos = SrcLen << 1;
    int SrcPos = SrcLen;

    while ( --SrcPos >= 0 )
    {
         unsigned char HiHalf = Src[SrcPos] >> 4;
         unsigned char LoHalf = Src[SrcPos] & 0x0F;
         Dest[--DestPos] = ( HiHalf <= 9 ) ? ( HiHalf + '0' ) : ( HiHalf + 55 );
         Dest[--DestPos] = ( LoHalf <= 9 ) ? ( LoHalf + '0' ) : ( LoHalf + 55 );
    }
}

    有兴趣的同学可以写个单元测试验证一下转化结果。或者改用查表法来转化,省去一些计算步骤。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值