序
今天有同事问了我一个问题:
传输协议的时候,接收到的是一串字符需要atoi这样的函数把内容读出来,因为定义的是一个Char型的数组,如果定义的是一个int型数组是不是不需要了?
我不知道我理解和表述的对不对,我告诉他的大体意思是(现在整理的,不知道当时说道啥,交流表达能力为负0.0),芯片处理时本质都是0和1的二进制数,而对于我们来讲各种格式只是表现的方式不一样,像‘a’,0x61,97这三个数放在内存中可能是同一个东西,但是表现给我们的却不一样,但是像‘1’和1在视觉上却给我们是一样的表现。
所以在传输协议数据时,我们要注意的是协议的规则,也就是发送方想要给你表达的内容,比如发送时将1格式化输出为‘1’,接收方就得0x31也就是‘1’将转成1再使用。
所以上面问题是用不用格式转换和发送方有没有进行格式变换有关
这里有个问题–以前弄过一个设置设备ID功能的需求,我在这端用的16进制格式输出到字符串,如0x15->“15”,但是后面我发现另外一个设备读来使用时是10进制读出来的也就是“15”->15当然设置时不会用0x0A这样的编号去设置ID号。不要问为什么有这样的需求,问就是不知道。。
毕竟协议都是人定的,所以只要双方认同使用按照相同的规范,就能正常通讯。
为什么发送时要转换成字符串格式
我认为最重要的一点是方便理解,一般在传输时有两种型式
ACSII
$cmd,set,num,123*ffHEX
7E 02 00 7B 7D 7E比如上面两条指令很明显第一条一眼就能看出功能,而下面的指令却完全看不出来什么意思,手动输入也不方便
当然,HEX使用时也需要通过转换得到数据,
比如上面使用7D表示123,这里可以直接将这一位赋值,也可以用01 02 03或者是31 32 33表示数据123,这时接收到指令就需要进行转换了。
常用的格式转换
所有的转换都能手动实现,但基本上都有相应的库函数去实现它,记录一下常用的转换函数。
函数 | 功能 | 说明 |
---|---|---|
头文件<stdio.h> | ||
sprintf | 格式输出到缓冲 | int sprintf(char * str,const char* format,…)例:sprintf(buf,%d%f,1,2.3) |
sscanf | 缓冲区按格式输入 | int sscanf(char * str,const char* format,…)例:sscanf(buf,%d%f,&num1,&num2) |
头文件<stdlib.h> | ||
atof | 字符串转浮点数 | double atoi(const char*str) |
atoi | 字符串转整数 | int atoi(const char*str) |
atol | 字符串转长整数 | long int atol(const char*str) |
strtod | 字符串转浮点数 | double strtod(const char*str,char**endptr) |
strtol | 字符串转长整数 | long int strtol(const char*str,char**endptr,intbase) |
strtoul | 字符串转无符号长整数 | unsigned long int strtol(const char*str,char**endptr,intbase) |