引言:随着项目的逐渐扩大,软件分层带来的是比如底层和协议栈的数据交互,或者底层和别的底层之间也会有数据交互,不可避免的就是各种各样的数据类型转化的问题,也有一些简单的过滤啊回写啊之类的,把最近遇见过得做个小总结吧:
1 物理地址的读写
void Xil_Out32(unsigned int * Addr, unsigned int Value) { volatile unsigned int *LocalAddr = (volatile unsigned int *)Addr; *LocalAddr = Value; } unsigned int Xil_In32(unsigned int * Addr) { return *(volatile unsigned int *) Addr; }
2 位操作
倒序
unsigned char bit_reverse(unsigned char c) { unsigned char buf = 0; int bit = 8; while(bit) { bit--; buf |= ((c & 1) << bit); c >>=1; } return buf; }
数0的个数
int CountZeroBit(int num) { int count = 0; while (num + 1) { count++; num |= (num + 1); //算法转换 } return count; } int main() { int value = 25; int ret = CountZeroBit(value); printf("%d的二进制位中0的个数为%d\n",value, ret); system("pause"); return 0; }
数1的个数
#include <stdio.h> int func(int x) { int countx = 0; while(x) { countx++; x = x&(x-1); } return countx; } int main() { printf("%d\n",func(9999)); return 0; }
设置如bit3,清除bit3
#define BIT3 (0x1<<3) static int a; void set_bit3(void) { a |= BIT3; } void clear_bit3(void) { a &= ~BIT3; }
3 大小端转化
//为大端: pPack[0] = (u8)((len >> 8) & 0xFF); pPack[1] = (u8)(len & 0xFF); //为小端: pPack[0] = (u8)(len & 0xFF); pPack[1] = (u8)((len >> 8) & 0xFF);
4 u8和u32的转化
void U32ToU8Array(uint8_t *buf, uint32_t u32Value) { buf[0] = ((u32Value >> 24) & 0xFF); buf[1] = ((u32Value >> 16) & 0xFF); buf[2] = ((u32Value >> 8) & 0xFF); buf[3] = (u32Value & 0xFF); } //注意:这里是字符数组,不是字符串 //字符串是以空字符(\0)结尾的char数组 void U8ArrayToU32(uint8_t *buf, uint32_t *u32Value) { *u32Value = (buf[0] <<24) + (buf[1] <<16) + (buf[2] <<8) + (buf[3] <<0); }
5十进制和字符串转化
如果只是单个十进制转字符串,使用sprintf函数就可以了。
如果是十进制数组:
u16 DectoStr (u8 *pSrc, u16 SrcLen, u8 *pObj) { u16 i=0; for(i=0; i<SrcLen; i++) { sprintf((char *)(pObj + i * 2), "%02d", *(pSrc + i)); } *(pObj + i * 2) = '\0'; return (i * 2); }
数组 5 20转为"520"
而字符串转十进制就比较复杂了
第一种,如果带负号 这个就是atoi函数的实现:
第二种,不带符号StrtoDec
最后一种转化为浮点数
//带符号
int my_atoi(const char *str) { int value = 0; int flag = 1; //判断符号 while (*str == ' ') //跳过字符串前面的空格 { str++; } if (*str == '-') //第一个字符若是‘-’,说明可能是负数 { flag = 0; str++; } else if (*str == '+') //第一个字符若是‘+’,说明可能是正数 { flag = 1; str++; }//第一个字符若不是‘+’‘-’也不是数字字符,直接返回0 else if (*str >= '9' || *str <= '0') { return 0; } //当遇到非数字字符或遇到‘\0’时,结束转化 while (*str != '\0' && *str <= '9' && *str >= '0') { value = value * 10 + *str - '0'; //将数字字符转为对应的整形数 str++; } if (flag == 0) //负数的情况 { value = -value; } return value; }
//不带
void StrtoDec(uint32_t *pbDest, char *pbSrc, int nLen) { int i; int tmp=0; if(nLen > 10) *pbDest = 0; tmp = 1; *pbDest = 0; for (i=nLen-1; i>=0; i--) { *pbDest += tmp*(*(pbSrc+i)-'0'); tmp = tmp*10; } } u16 DectoStr (u8 *pSrc, u16 SrcLen, u8 *pObj) { u16 i=0; for(i=0; i<SrcLen; i++) { sprintf((char *)(pObj + i * 2), "%02d", *(pSrc + i)); } *(pObj + i * 2) = '\0'; return (i * 2); }
浮点
//m^n函数 //返回值:m^n次方. u32 NMEA_Pow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } //str转换为数字,以','或者'*'结束 //buf:数字存储区 //dx:小数点位数,返回给调用函数 //返回值:转换后的数值 int NMEA_Str2num(u8 *buf,u8*dx) { u8 *p=buf; u32 ires=0,fres=0; u8 ilen=0,flen=0,i; u8 mask=0; int res; while(1) //得到整数和小数的长度 { if(*p=='-'){mask|=0X02;p++;}//是负数 if(*p==','||(*p=='*'))break;//遇到结束了 if(*p=='.'){mask|=0X01;p++;}//遇到小数点了 else if(*p>'9'||(*p<'0')) //有非法字符 { ilen=0; flen=0; break; } if(mask&0X01)flen++; else ilen++; p++; } if(mask&0X02)buf++; //去掉负号 for(i=0;i<ilen;i++) //得到整数部分数据 { ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0'); } if(flen>5)flen=5; //最多取5位小数 *dx=flen; //小数点位数 for(i=0;i<flen;i++) //得到小数部分数据 { fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0'); } res=ires*NMEA_Pow(10,flen)+fres; if(mask&0X02)res=-res; return res; } #include <stdio.h> #include <stdlib.h> char *FloatToString(double d,char *str) { char str1[40]; int j = 0,k,i; i = (int)d;//浮点数的整数部分 while(i > 0) { str1[j++] = i % 10 + '0'; i = i / 10; } for(k = 0;k < j;k++) { str[k] = str1[j-1-k];//被提取的整数部分正序存放到另一个数组 } str[j++] = '.'; d = d - (int)d;//小数部分提取 for(i = 0;i < 10;i++) { d = d*10; str[j++] = (int)d + '0'; d = d - (int)d; } while(str[--j] == '0'); str[++j] = '\0'; return str; } int main(int argc, char **argv) { double d = 365.80323; char str[20]; FloatToString(d,str); printf("%s\n",str); return 0; }
6 16进制和字符串转化
void StrToHex(char *pbDest, char *pbSrc, int nLen) { char h1,h2; char s1,s2; int i; for (i=0; i<nLen/2; i++) { h1 = pbSrc[2*i]; h2 = pbSrc[2*i+1]; s1 = toupper(h1) - 0x30; //toupper 转换为大写字母 if (s1 > 9) s1 -= 7; s2 = toupper(h2) - 0x30; if (s2 > 9) s2 -= 7; pbDest[i] = s1*16 + s2; } } void StrToHex(char *pbDest, char *pbSrc, int nLen) { char h1,h2; char s1,s2; int i; for (i=0; i<nLen/2; i++) { h1 = pbSrc[2*i]; h2 = pbSrc[2*i+1]; s1 = toupper(h1) - 0x30; //toupper 转换为大写字母 if (s1 > 9) s1 -= 7; s2 = toupper(h2) - 0x30; if (s2 > 9) s2 -= 7; pbDest[i] = s1*16 + s2; } } u16 Hex2StringArray (u8 *pSrc, u16 SrcLen, u8 *pObj) { u16 i=0; for(i=0; i<SrcLen; i++) { sprintf((char *)(pObj + i * 2), "%02X", *(pSrc + i)); } *(pObj + i * 2) = '\0'; return (i * 2); }
7 数据回写
#include < stdlib.h> #include < stdio.h > #include < errno.h> #include < sys/stat.h> #include < unistd.h> #define BUFF_SIZE 4096 int create_test_file(char* file_path) { FILE* pf = fopen(file_path, "w"); if (pf == 0) { return 0; } int i = 10000, j = 0; for (; i > 0; --i) { for (j = 0; j < 10; ++j) { fprintf(pf, "%d", j); } fprintf(pf, "%s", "\n"); } fflush(pf); fclose(pf); return 1; } size_t get_file_size(const char *path) { size_t fsize = -1; struct stat stbuff; if (stat(path, &stbuff) < 0) { return fsize; } else { fsize = stbuff.st_size; } return fsize; } void reverse_buff(char* buff, int buflen) { int i = 0, j = buflen / 2, k = buflen % 2; char c; for ( ; i < j; ++i) { c = buff[i]; buff[i] = buff[buflen - i - 1]; buff[buflen - i - 1] = c; } } void change_buff_block(FILE* pf, size_t fsize, int left_block, int left_size, int right_size) { char buff1[BUFF_SIZE]; char buff2[BUFF_SIZE]; size_t rs, ws; fseek(pf, BUFF_SIZE * left_block, SEEK_SET); rs = fread(buff1, left_size, 1, pf); reverse_buff(buff1, left_size); if (right_size > 0) { fseek(pf, fsize - BUFF_SIZE * left_block - right_size, SEEK_SET); rs = fread(buff2, right_size, 1, pf); reverse_buff(buff2, right_size); fseek(pf, BUFF_SIZE * left_block, SEEK_SET); ws = fwrite(buff2, right_size, 1, pf); fseek(pf, fsize - BUFF_SIZE * (left_block + 1), SEEK_SET); ws = fwrite(buff1, left_size, 1, pf); } else { fseek(pf, BUFF_SIZE * left_block, SEEK_SET); ws = fwrite(buff1, left_size, 1, pf); } } int main(int argc, char* argv[]) { if (argc < 1) { printf("please pass test file as first arg!"); return -1; } char* file = argv[0]; if (argc > 1 && argv[1][0] == 'c' && !create_test_file(file))// if create test file { printf("create test file failed!"); return -1; } size_t fsize = get_file_size(file); if (fsize <= 0) { printf("file not exists or is empty!"); return -1; } size_t remsize = fsize % BUFF_SIZE; int buff_cnt = fsize / BUFF_SIZE + (remsize > 0 ? 1 : 0); int inv_cnt = buff_cnt / 2; FILE* pf = fopen(file, "r+"); if (pf == 0) { printf("cannot open file!"); return -1; } int i, j; for (i = 0; i < inv_cnt - 1; ++i) { change_buff_block(pf, fsize, i, BUFF_SIZE, BUFF_SIZE); } if (buff_cnt % 2 > 0) { change_buff_block(pf, fsize, i, BUFF_SIZE, BUFF_SIZE); change_buff_block(pf, fsize, ++i, remsize, 0); } else if (remsize > 0) { change_buff_block(pf, fsize, i, BUFF_SIZE, remsize); } else { change_buff_block(pf, fsize, i, BUFF_SIZE, BUFF_SIZE); } fflush(pf); fclose(pf); printf("test ok!"); return 0; }