shafeishafei 发表于 2011-10-18 09:33

求十六进制字符串转化为字符数组的程序

void Hex2Byte(uchar*str,ucha*byte)
{
   uchar tmp;
   while(*str!=0)
       {
         tmp=((*str)<<4)&0xf0;
         str++;
         if(*str==0)
         {
            *byte=(tmp>>4)&0x0f;
            return;
         }
         tmp+=(*str)&0x0f;
         *byte=tmp;
         bye++;         
       }

}
这个破程序就是流行很多书籍的一个关于十六进制字符串转换成字符数组的一个小程序,
但是我怎么也看不懂,我自我反思是因为,我对单片机存储字母的方式不甚了解。如果
哪位大侠对这个比较了解,可以结合这个程序给我上一课,好吗?
万分感激

HWM 发表于 2011-10-18 13:07

本帖最后由 HWM 于 2011-10-18 16:51 编辑

这和单片机没有特别关系。仅是将一组用字节存储的四位数据合并成一个字节存储两个四位数据。

void Hex2Byte(uchar*str,ucha*byte)
{
   uchar tmp;
   while(*str!=0) // 是否终结(NULL作为终结标志)?
       {
         tmp=((*str)<<4)&0xf0;// 取HEX(八位表示的四位数),左移四位
         str++;// 指向下一个HEX
         if(*str==0) // 是否终结?
         {
            *byte=(tmp>>4)&0x0f;// 若仅单个四位数,则向右移回四位
            return;// 结束
         }
         tmp+=(*str)&0x0f; // 两个四位的HEX(原来分别放在相邻两个不同的字节里),合并放在一个字节里
         *byte=tmp; // 存入输出字节
         bye++; // 下一个字节
       }

}


另外,请别随意称别人的程序为“破程序”,至少等自己修炼到一定程度后再评论别人。

shafeishafei 发表于 2011-10-18 14:08

我懂了,比如主机要发十进制数字35.
首先主机把它变成十六进制数字:0x23;即二进制数字:00100011;
好,针对二进制的数字高四位:0010,它的十六进制数字是“2”
此时我查表得“2”的ASii码是:00110010,(当然单片机是用自己的程序算出ASII码值)即(0x32)将它赋值给SBUF,发出去
然后,针对二进制的数字低四位:0011,它的十六进制数字是“3”
此时查表得“3”的ASII码是:00110011,即(0x33),然后将将它赋值给SBUF,发出去
上面这个过程就是把字符数组转换为十六进制字符串的基本过程,当然发完所有的东西以后
尾部还要发一个"\0"表示字符串结尾,上面的问题就是在这个背景下提出的
现在进入正题:
比如说,从机接受上面的数据。首先接收到的是00110010,然后接收到的是:00110011
上面的程序就是把接收这两个字节的数据,然后拼成一个字节的数据,而且这个数据就是十进制的35
我现在把程序处理数据的步骤系统说一遍
首先接收到的是00110010,这个数字算术左移四位是:00100000,然后与0xf0相与,其实还是:00100000
其次接收到的是00110011,这个数字与0x0f相与,变成:00000011
然后:00100000+00000011=00100011,正好是我们要发送的数字:十进制数字35
从这个算法中我们总结一下就是:主机会把四个bit,变成一个Byte,发出去
然后从机会把接收到的这个Byte,通过一些计算,还原成最初的那四个bit
这个就是使用十六进制ASII码传送数据的基本方式
虽然这个问题很小,有的人一思考便知晓其中的内涵,但是我开始接触这个,想破脑壳也想不出来
中午和实验室哥们讨论问题的时候,受了师兄启发,茅塞顿开
这段程序很多书上都是,确实很好,当时我还以为是个错误程序,现在觉得是我错了


ruiwei0201 发表于 2011-10-18 16:05

这真是个错误程序! 举例说明:字符'F' 左移4位变成了什么?其ASCII码值为46H 0100$0110,显然左移4位后变成了0110$xxxx,即6XH,不是我们想要的结果!

HWM 发表于 2011-10-18 17:01

to LZ:

这仅是个将四位二进制数(占一个字节)压缩合并成一个字节存储两个四位二进制数的程序——故有名Hex2Byte。

shafeishafei 发表于 2011-10-18 18:18

4# ruiwei0201
没有"F",只有0到9,和a到f,所以不存在你说的情况。
还有什么问题,我们可以探讨一下,呵呵

shafeishafei 发表于 2011-10-18 18:29

5# HWM [
请查阅人民邮电出版社《单片机通信技术与工程实践》第207~208页
也许是我问题没有交代清楚吧

ruiwei0201 发表于 2011-10-19 08:51

4# ruiwei0201
没有"F",只有0到9,和a到f,所以不存在你说的情况。
还有什么问题,我们可以探讨一下,呵呵
shafeishafei 发表于 2011-10-18 18:18 https://bbs.21ic.com/images/common/back.gif
除了ascii码值不同,'f'和'F'有啥区别?

shafeishafei 发表于 2011-10-19 12:19

8# ruiwei0201
比如说,我数据存储的是:11010101110011001100.。。。
这样的东西,我每四个二进制数变成一个十六进制,只有0~9,和a~f,
所以不存在你说的大写字母的出现
我不知道我说错了没有

xhtxzxw 发表于 2011-10-19 14:04

有俩错误,一个隐患:
1、只能处理字符‘0’~‘9’·的组成的串。
2、串长度没有限定,算出来的值有可能一个字节装不下的。
3、没有对串中字符的合法性做任何检测,合法字符只能是‘0’~’9‘,‘a'~'f', 'A'~'F'。

另外,还有有一些属于脱裤子放屁的操作。总之,这是一段垃圾代码,如果还能叫做代码的话。
页: [1]
查看完整版本: 求十六进制字符串转化为字符数组的程序