你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C语言的一些转换工具函数

[复制链接]
gaosmile 发布时间:2020-8-9 21:31
1、字符串转十六进制

3 w3 H9 Z  N# |7 F5 K$ _1 K# j
代码实现:
& Z: i3 S8 f' W+ O/ c7 {2 S% Q
void StrToHex(char *pbDest, char *pbSrc, int nLen)
3 A9 s+ @/ ]: m5 K/ _$ e; [{7 ?3 B6 e, B+ M3 V& ~( Q& [" ]
  char h1,h2;& H4 i/ v. m0 o) h, x% y! Z* M0 i
  char s1,s2;6 A5 q2 R1 Z; C! o
  int i;* ?& K: r* C+ t; H! R
) b% y- _2 q" @4 o
    for (i=0; i<nLen/2; i++)2 }9 }- {  @% `
    {  U6 Q& z0 {' A* h/ ~
        h1 = pbSrc[2*i];
( ~. ]$ b3 ~3 H2 g" u/ Y+ {        h2 = pbSrc[2*i+1];% h  Q  B2 F/ E9 y

; d5 _3 L/ g5 |! d        s1 = toupper(h1) - 0x30; //toupper 转换为大写字母
8 h  I' F: t0 n& E        if (s1 > 9)
, @$ {5 D9 ~7 v+ Z! ~            s1 -= 7;
" @2 C  ^% O  z. b0 U7 M        s2 = toupper(h2) - 0x30;$ o7 @5 j3 X' [6 F' {1 _
        if (s2 > 9)7 p* p, N0 G! W# Z) O- _; }
            s2 -= 7;  E! Q3 U$ c; r* o: E
, p; z8 ]1 ?$ E. h& R8 Q5 W
        pbDest = s1*16 + s2;
# R$ d% E4 Z; o  O    }4 q. c/ \) Y- W% ?  A
}
& ]4 D& d3 \6 K. P0 m/ I
, i. @- [2 w4 |2 d/ z  _
2、十六进制转字符串
代码实现:
! W$ w7 E1 N% m- m% k$ C
void HexToStr(char *pszDest, char *pbSrc, int nLen)
/ J0 a1 _. P3 j+ M! \7 Q{, l4 I% ]5 u1 o& I
    char    ddl, ddh;8 G( o, X: ^8 r4 i
    for (int i = 0; i < nLen; i++)
. [( j4 |9 x1 l5 R    {
( `+ N" _( E% u( V% t  ?0 H        ddh = 48 + pbSrc / 16;
( N) ?' ^6 j- z. }        ddl = 48 + pbSrc % 16;
/ t  K( u3 `' h) d; h        if (ddh > 57) ddh = ddh + 7;
* E8 Q$ h6 J6 y8 w9 L        if (ddl > 57) ddl = ddl + 7;
1 S: p8 v: }  a: u        pszDest[i * 2] = ddh;
! }# O( Q% J! Z9 x! b# A) E        pszDest[i * 2 + 1] = ddl;
+ l: q* s6 _4 b- i$ f0 h/ ?5 f    }; `) S+ M0 K7 ^. x9 t$ t' u
    pszDest[nLen * 2] = '\0';
8 f. ]" U4 O% h}

( A0 n& j# D( \& N; t; v

或者

u16 Hex2StringArray (u8 *pSrc,  u16 SrcLen, u8 *pObj)+ M6 J- G2 t# Q0 v
{+ z' ^+ [8 }3 c
    u16 i=0;
3 F$ C' c0 I# U4 Q
* d3 d8 L* Y5 ~    for(i=0;    i<SrcLen;   i++)) n+ ?- F' R# T5 M4 k1 S! n3 q4 ~
    {. W3 K- a7 Q. t% w1 K6 `
        sprintf((char *)(pObj + i * 2), "%02X", *(pSrc + i));! U# o. ~$ w  n/ `
    }, h* o& E7 y8 E1 n# W9 a
    *(pObj + i * 2) = '\0';
7 G5 |4 w/ ^. n. g- U4 ^    return  (i * 2);
$ F5 ?- x' K/ j! T+ \}

" j* t$ G7 K  {3 U
7 u& L, f7 @( m) [8 V) n
效果:十六进制:0x13 0xAA 0x02转为字符串:”13AAA2”
, ~" f# [* {1 d/ R; A& n( V
3、字符串转十进制
代码实现:
5 ^3 U" o* ~! u
第一种,如果带负号 这个就是atoi函数的实现:

, w' n, `" @4 i/ Z! x  J
int my_atoi(const char *str)# O9 E! h) V: d* r
{
6 ~" P8 Q) s9 Q- H+ M1 V( D3 ?# z    int value = 0;! p1 [6 h. u& x$ s
    int flag = 1; //判断符号9 l* ~3 V: g$ j- z6 y
    while (*str == ' ')  //跳过字符串前面的空格! d4 q) i/ M$ |% L& Z6 x: ]
    {
/ U1 \/ H/ J( Y        str++;
% N; a6 T) {  \$ N2 J! @. @    }
) n) _7 Z& [. ]' d. v    if (*str == '-')  //第一个字符若是‘-’,说明可能是负数. ~4 q4 \5 u; f! w
    {. F. N1 R) v) E9 O8 k. Y
        flag = 0;1 v# v3 B' M7 W8 ^7 l
        str++;
/ N' u6 c$ G  Y& V( D5 h: v    }
( F6 N' h8 T; T0 K    else if (*str == '+') //第一个字符若是‘+’,说明可能是正数
$ @# V( ~+ z9 i( F- ^5 T    {* A  S# h; Z: {; y, O+ Q: i
        flag = 1;
2 y1 C* p  a3 Q! z6 O% z3 v        str++;" k3 R; `" g1 k; z, P
    }//第一个字符若不是‘+’‘-’也不是数字字符,直接返回06 ~) p9 ?7 i9 S( a, H. f6 P
    else if (*str >= '9' || *str <= '0')
. N& }2 K5 v" I- E1 y    {
% a5 y  b! K, q8 g9 h2 q9 ?        return 0;    8 u# G/ P2 S" H5 K% |% x1 f
    }
) @4 F0 j+ a8 ~    //当遇到非数字字符或遇到‘\0’时,结束转化
' ~+ I% y6 [# h& d    while (*str != '\0' && *str <= '9' && *str >= '0')( j; |; \3 o+ }, X: C
    {- X  c1 d* s. e3 O  Z
        value = value * 10 + *str - '0'; //将数字字符转为对应的整形数
6 _! E" x  z% s9 e* M1 o. P        str++;3 p$ P+ _  ^! L/ Q" H% F
    }
, a( ~; ?; P1 o* B2 A/ X* ^' f    if (flag == 0) //负数的情况6 y( e# B+ Q( M9 ~
    {2 T8 U! N, i4 e' ?" [" b: p9 `( K
        value = -value;
, d( w7 o7 X- k( B- j    }
" A5 {, \6 I) U9 H8 X# Y7 b    return value;8 L  ]# W# e+ Z  `, L
}

& }( \, l# \6 W( r9 f
- q8 l/ w3 a& _2 E8 \
效果:字符串:”-123” 转为 -123

5 B1 x' T% q9 T! Q# j3 k$ r3 Y  g9 v
第二种,如果不带负号:

" e' L* ]0 s  k5 P
void StrtoDec(uint32_t *pbDest, char *pbSrc, int nLen)+ i' s* H- c4 Z, a' h( X
{
0 O& F1 @: \7 q2 [  d/ [    int i;
8 R0 X2 V; e& O* D/ X# J, [3 l    int tmp=0;/ t- W! Y$ J! z, X. a
    if(nLen > 10)  c: [; b- x7 z" @& E/ ^( d
        *pbDest = 0;
' {4 ?0 C+ R+ a) J/ e" c    tmp = 1;
: ?' s" O% V- n" j) O$ I9 F3 P    *pbDest = 0;
2 o7 x, x. M6 X  {. i    for (i=nLen-1; i>=0; i--)# `: B2 v5 v. d6 ]5 f2 H1 g- A
    {( D- p& Z' u2 }) i( t
        *pbDest += tmp*(*(pbSrc+i)-'0');
; d, q3 N& h9 }+ G" F0 C: i        tmp = tmp*10;
% @8 b7 ?( M* R1 k    }* _& c( v! I! I7 n1 J2 I
}
# @6 ]( i' s6 u4 Y

7 d7 i# k1 ^, ^0 W- n! Y
效果:字符串:”123” 转为 123

2 l$ w# t, }' G4 x6 ^
第三种:包含转为浮点数:

( C* b( P1 \. c% g0 m; c( A6 P: W
//m^n函数" q- q7 h# f  y* T2 R( \
//返回值:m^n次方.
) O4 f0 z" l2 u3 fu32 NMEA_Pow(u8 m,u8 n)
8 t# _- d/ N! A) G6 v{
% M8 q! v" F/ {- G    u32 result=1;   
+ X8 ~* Y0 M9 J5 P0 o    while(n--)result*=m;   
( z& h% T3 m& L8 u    return result;6 u+ b; W$ r- t, h$ P7 ~3 U, K" B
}1 T% J6 N  h1 S- ^) H6 }, Z0 [5 T
//str转换为数字,以','或者'*'结束
3 a. A; ?! l8 K; z, O( A6 U$ I8 N//buf:数字存储区' o! j7 @' I7 r) X1 A6 O
//dx:小数点位数,返回给调用函数6 D7 V' u# c! s2 S- i- u. `! q/ L* U
//返回值:转换后的数值
( \1 h( W8 H' j9 ^; r) e/ S' uint NMEA_Str2num(u8 *buf,u8*dx)6 ~( z9 A! }$ N( s1 V$ ]3 y+ w
{
* j5 d1 O+ p) Z    u8 *p=buf;' g* C) o9 E) ^' x
    u32 ires=0,fres=0;
6 e9 i( C3 |6 Z5 T" G( b: @* @    u8 ilen=0,flen=0,i;
$ z5 Z+ r3 R  T! L9 x    u8 mask=0;' \3 F" u$ i* ]2 }2 ?' A% l) B2 `
    int res;' u7 ]" a& f: R, J
    while(1) //得到整数和小数的长度  N5 a/ {6 a3 ?$ M" y2 |% g2 }
    {
. [$ q+ B4 v. n8 K" D1 k        if(*p=='-'){mask|=0X02;p++;}//是负数4 T) Y" C) `& Z% c" U& `* X6 K! `
        if(*p==','||(*p=='*'))break;//遇到结束了9 G- [* G/ Q- H; Z0 T
        if(*p=='.'){mask|=0X01;p++;}//遇到小数点了
+ M+ _9 ]4 j  e        else if(*p>'9'||(*p<'0'))   //有非法字符8 H4 M; _* |  o
        {   
! Y) V8 l$ z4 q( U# }2 k' L            ilen=0;
  p4 o, K1 m# K) T6 ~            flen=0;9 t% i* R4 V- V0 ]- @
            break;  y  \6 }+ {1 Z
        }   . |) R7 f8 M+ Q
        if(mask&0X01)flen++;
" |5 ?5 @' C& a) z6 ]        else ilen++;7 L4 k$ ^5 w0 o8 F* l- E- w5 `2 q
        p++;6 f7 s: |1 Q/ f% X  o/ b
    }
9 `& l! m8 ^9 ]) N  I    if(mask&0X02)buf++; //去掉负号
6 l" g' n+ R) |& p    for(i=0;i<ilen;i++) //得到整数部分数据% C& {4 g% @1 a: x) f6 \0 j. }
    {  
8 N' t4 a* z* w5 X        ires+=NMEA_Pow(10,ilen-1-i)*(buf-'0');
2 x( z! c# w" M& ?+ d    }1 b/ ?+ V" V# m1 H9 o5 O
    if(flen>5)flen=5;   //最多取5位小数6 x( }" d5 r# T, _8 R
    *dx=flen;           //小数点位数- R# Y1 p! _. x; A8 _! Q7 P
    for(i=0;i<flen;i++) //得到小数部分数据! _# S+ f7 |8 D$ {! @% y8 D
    {  ! q1 ~! e6 ^! l( G- S( _3 \
        fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');1 a- L: ~5 E7 ^  {$ B8 L) F3 p
    }
6 j" _: P# D% r7 r9 P/ u    res=ires*NMEA_Pow(10,flen)+fres;
9 E& z. R% y, ]7 Q' {: H1 Q  A    if(mask&0X02)res=-res;         
: \; K# m. ]! N+ d. K0 b5 U    return res;+ S! ~7 J# u' p2 j' j
}
6 r0 {( `3 t) m

2 P: F: \! l) R. ]! n: v& S5 b
效果:字符串:”123.456” 先转为 123456,然后除以1000得到123.456

6 Y. K: _7 v4 ~3 Q  E% P% O
4、十进制转字符串
6 i4 S( M5 P! B& j& x, v
代码实现:

5 Q1 l" ]1 k1 u- V# C$ F, k
如果只是单个十进制转字符串,使用sprintf函数就可以了。
; J' H* J6 g( I' e
如果是十进制数组:

+ \; J$ q: {9 s/ \9 i) M0 i3 Q2 U
u16 DectoStr (u8 *pSrc, u16 SrcLen, u8 *pObj)" s9 M5 P3 H/ }2 D
{
6 C4 b( `: {$ ~- Q    u16 i=0;
' ]: N5 e6 X# e% n- _" k
/ S7 z1 E, P6 E    for(i=0;    i<SrcLen;   i++)$ ^4 q, p3 `: y& ^! ^
    {
  ~' R/ x- |# L. j% h$ N* y        sprintf((char *)(pObj + i * 2), "%02d", *(pSrc + i));
& e% }" v+ Y" g; d* @    }. w# O5 C4 M# J: _1 v  D
    *(pObj + i * 2) = '\0';
4 S9 ^! G' g/ z5 b1 c3 [    return  (i * 2);
3 Q5 F+ A- T! y2 v}

; C* _  V0 [$ P+ X" |6 T
' j9 a4 [1 u( ^. U& u: q
效果:十进制数组13 14转为字符串“1314”

: x- H) o6 g% w
5、u8、u32转换
: {1 z* j! C1 R( a& ]) @0 d( o
举个栗子:ASCII码里

. j- i, d2 k& @4 G
! E  b1 |' g; {4 F  \8 B: e
这里写图片描述 字符‘A’ , 一个字节8bit ,即u8 十六进制为 0x41 二进制为 0100 0001

" D1 H& L$ u* m
而对应的十进制为 65 整型65,4个字节32bit,即u32 十六进制为 0x41 二进制为 0000 0000 0000 0000 0000 0000 0100 0001

  ^6 t* g' Z( ]$ c- V* G
将u32数转换成u8数组
  T* ?  X" G, [- O+ g: W
注意:这里是字符数组,不是字符串

9 D, F" J5 H( w) d, [/ e9 ?
字符串是以空字符(\0)结尾的char数组
1 _1 A$ ]  a  G8 B' `4 u  P  C
void U32ToU8Array(uint8_t *buf, uint32_t u32Value){; l# Y# D$ H$ V
    buf[0] = ((u32Value >> 24) & 0xFF);
/ m2 S2 J* A( ]( H0 q    buf[1] = ((u32Value >> 16) & 0xFF);5 a- D7 n8 h  V0 ~4 }
    buf[2] = ((u32Value >> 8) & 0xFF);
# N+ `$ Z) R1 ]( X+ h% e1 p    buf[3] = (u32Value & 0xFF);8 w- `0 o$ h  R" A* C0 v8 f
}

6 z6 x6 i' @5 t
' K8 q$ x- Q6 P
效果:整型 50 转字符数组 {‘\0’,’\0’,’\0’,’2’}
8 v$ P; I( R, z; c$ L: S# {$ w- t
u8数组转u32
1 }5 N, q5 p. g6 s4 v
void U8ArrayToU32(uint8_t *buf, uint32_t *u32Value)$ \6 k4 M5 J. e' B6 L- G
{; W$ b3 W6 y1 I5 \, O1 s
    *u32Value = (buf[0] <<24) + (buf[1] <<16) + (buf[2] <<8) + (buf[3] <<0);0 X* r  M; ~, x1 ^- w, F
}

' d6 b  T: O+ c# G: w
- t7 B7 y! ~. T- L/ W8 ~7 E) J$ R
效果:字符数组 {‘\0’,’\0’,’\0’,’2’}转为整型 50

0 {2 ~# d+ A! L0 F7 d% g
6、大端小端

/ l- l; e9 I4 C3 P# W0 R
最后就是大小端问题了。STM32 默认是小端模式的,那么该如何转为大端?

( L3 P( v1 L* a, @2 m
1、转为大端

% I* u: Q4 k$ r* k1 g- `
为大端:
1 g' @7 k! i- K  o' xpPack[0] = (u8)((len >> 8) & 0xFF);& N0 V/ U+ }1 Y7 z% \3 M
pPack[1] = (u8)(len & 0xFF);& D; [' r/ V' k! V, G

" K! `. c" l( Q. c7 [" M7 r为小端:7 i1 e6 @3 ?4 N
pPack[0] = (u8)(len & 0xFF);. H9 r' v% Y4 m7 I/ [# ]: n
pPack[1] =  (u8)((len >> 8) & 0xFF);
1 {  Q) ~* d$ M  \8 }) v% m
& }$ Z& u1 C/ B* ~/ o
效果:len为数据类型为 u16(short),比如 0x11 0x22,转为u8(usigned char)数组。
! M+ W9 j2 C9 {3 |2 g" q! V
大端为:

, T- x( c4 C! [
pPack[0] (0x11 ) + a  l4 B8 k3 g
pPack[1] (0x22)

* M8 p/ l, J  W

/ ]: V/ |5 \6 Y& P
小端为:

/ |7 m. d5 `  Y6 h$ w; m8 K
pPack[0] (0x22) & b! b# t( a+ Z( w3 J% q" o  ]
pPack[1] (0x11)

/ J- B+ L# ]  P& R; n. l- @
赞 收藏 3 评论0 发布时间:2020-8-9 21:31

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版