C语言常用转换函数实现原理

在进行C/C++的编程时,经常需要用到进制转化、字符转化。虽然C提供了一些转化函数,例如atoi 和itoa等,但是还是有一些比较经典常用的自己封装的函数比较使用。

一、字符串转十六进制

直接上代码:

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 HexToStr(char *pszDest, char *pbSrc, int nLen)
{
    char    ddl, ddh;
    for (int i = 0; i < nLen; i++)
    {
        ddh = 48 + pbSrc[i] / 16;
        ddl = 48 + pbSrc[i] % 16;
        if (ddh > 57) ddh = ddh + 7;
        if (ddl > 57) ddl = ddl + 7;
        pszDest[i * 2] = ddh;
        pszDest[i * 2 + 1] = ddl;
    }
    pszDest[nLen * 2] = '\0';
}

或者:

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);
}

 效果:十六进制:0x13 0xCC 0x02转为字符串:”13CC02”

三、字符串转十进制

代码实现:

第一种,如果带负号 这个就是atoi函数的实现:


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;
}

效果:字符串:”-153” 转为 -153

第二种,如果不带负号

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;
    }
}

效果:字符串:”123” 转为 123

第三种:包含转为浮点数

//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;
}

效果:字符串:”123.456” 先转为 123456,然后除以1000得到123.456

四、十进制转字符串

代码实现:

    如果只是单个十进制转字符串,使用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);
}
 效果:十进制数组13 14转为字符串“1314”

五、u8、u32转换

举个例子:ASCII码里:

这里写图片描述字符‘A’ , 一个字节8bit 。

即u8 十六进制为:0x41

 二进制为:0100 0001

而对应的十进制为65整型65,4个字节32bit。

即u32 十六进制为:0x41

二进制为:0000 0000 0000 0000 0000 0000 0100 0001

将u32数转换成u8数组。

注意:这里是字符数组,不是字符串。

字符串是以空字符(\0)结尾的char数组效果:整型 50 转字符数组 {‘\0’,’\0’,’\0’,’2’}

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);
}

效果:整型 50 转字符数组 {‘\0’,’\0’,’\0’,’2’} 

void U8ArrayToU32(uint8_t *buf, uint32_t *u32Value)
{
    *u32Value = (buf[0] <<24) + (buf[1] <<16) + (buf[2] <<8) + (buf[3] <<0);
}

 效果:字符数组 {‘\0’,’\0’,’\0’,’2’}转为整型 50

六、大小端(高低位)转换

 STM32 默认是小端模式的,那么该如何转为大端?

//转为大端:
pPack[0] = (u8)((len >> 8) & 0xFF);
pPack[1] = (u8)(len & 0xFF);

//转为小端:
pPack[0] = (u8)(len & 0xFF);
pPack[1] =  (u8)((len >> 8) & 0xFF);

效果:len为数据类型为 u16(short),比如 0x11 0x22,转为u8(usigned char)数组。

 大端为:

pPack[0] (0x11)
pPack[1] (0x22) 

小端为:


pPack[0] (0x22)
pPack[1] (0x11)

七、把ASCII字符转16进制

/***************************
函数名:Ascii2Hex
功能描述:把Ascii字符转16进制
参数:Ascii字符
返回:16进制
***************************/
unsigned char Ascii2Hex( unsigned char bAscii )		
{
	unsigned char bHex = 0;
    if( ( bAscii >= 0 ) && ( bChar <= 9 ) )
    {
        bHex = bAscii + 0x30;
    }
    else if( ( bAscii >= 10 ) && ( bAscii <= 15 ) )
    {
        bHex = bAscii + 0x37;
    }
    else
    {
        bHex = 0xff;
    }
    return bHex;
}
uint8_t char_2_hex(uint8_t *src)
{
    uint8_t desc;

    if((*src >= '0') && (*src <= '9'))
        desc = *src - 0x30;
    else if((*src >= 'a') && (*src <= 'f'))
        desc = *src - 0x57;
    else if((*src >= 'A') && (*src <= 'F'))
        desc = *src - 0x37;

    return desc;
}

八、十六进制转ASCII实现

/***************************
函数名:Hex2Ascii
功能描述:把16进制转Ascii字符
参数:16进制
返回:Ascii字符
***************************/
unsigned char Hex2Ascii( unsigned char bHex )		
{
	unsigned char bAscii = 0;
    if( ( bHex >= '0' ) && ( bHex <= '9' ) )
    {
        bAscii =  bHex - '0';
    }
    else if( ( bHex >= 'A' ) && ( bHex <= 'F' ) )
    {
        bAscii = bHex - '7';
    }
    else if( ( bHex >= 'a' ) && ( bHex <= 'f' ) )
    {
        bAscii = bHex - 0x57;
    }
	else
	{
		bAscii = 0xff;
	}
    return bAscii;
}
uint8_t hex_2_char(uint8_t *src)
{
    uint8_t desc;

    if((*src >= 0) && (*src <= 9))
        desc = *src + 0x30;
    else if((*src >= 0xA) && (*src <= 0xF))
        desc = *src + 0x37;
    
    return desc;
}

九、把16进制转BCD值

/***************************
函数名:Hex2Bcd
功能描述:把16进制转BCD值
参数:16进制值
返回:BCD值
***************************/
u_8 Hex2Bcd( u_8 HexCode )
{
    return( ( HexCode % 10 ) + ( HexCode / 10 * 16 ) );
}

十、把BCD值转2进制

/***************************
函数名:Bcd2Bin
功能描述:把BCD值转2进制
参数:BCD值
返回:2进制值
***************************/
u_8 Bcd2Bin( u_8 BcdCode )
{
    return( ( ( ( BcdCode >> 4 ) & 0x0F ) * 10 ) + ( BcdCode & 0x0F ));  
}

十一、把2进制转BCD值 

/***************************
函数名:Bin2BCD
功能描述:把2进制转BCD值
参数:2进制值
返回:BCD值
***************************/
u_8 Bin2BCD( u_8 BinCode )
{
    return( ( ( (BinCode)/10 ) << 4 ) + ( (BinCode) %10 ));  
}

十二、把x值的第i位置为1

/********把x值的第i位置为1*************/
#define X_SETBIT( x , i )       ( (x) |= ( 0x1 << (i) )) 

十三、把x值的第i位清为0

/**********把x值的第i位清为0**********/
#define X_CLRBIT( x , i )       ( (x) &= ( ~( 0x01 << (i) )))

十四、判断x值的第i位是否为1

/*********判断x值的第i位是否为1**********/
#define X_CHKBIT( x , i )       ( ((x) >> (i) ) & 0x01 )

十五、取i值的低8位

/*********取i值的低8位**********/
#define GET_4_BYTE(i)    (u_8)( ( (i) & 0xFF ) >> 0 )

十六、取i值的8-16位

/*********取i值的8-16位**********/
#define GET_3_BYTE(i)    (u_8)( ( (i) & 0xFF00 ) >> 8 )

十七、取i值的16-24位

/*********取i值的16-24位**********/
#define GET_2_BYTE(i)    (u_8)( ( (i) & 0xFF0000 ) >> 16 ) 

十八、取i值的24-32位

/*********取i值的24-32位**********/
#define GET_1_BYTE(i)    (u_8)( ( (i) & 0xFF000000 ) >> 24 )

十九、某几位变,某几位不变

Send[8] = (Send[8]&0xC0)|0x1C 
& 不变 | 变
C0为不变,1100 0000 【11这两位不被改变】

/*
Number 需要被改变的数
High_Low 设置的高低位
Wei_Num 设置某一位
*/
char BIT_hand(unsigned char Number,unsigned char High_Low,unsigned char Wei_Num)
{
    unsigned char Temp;
    Wei_Num= Wei_Num-1;
    if(High_Low==0)
    {   //置低
       Number &= (~(0x01<<Wei_Num));
    }
    if(High_Low==1)
    {
      Number=Number|(0x01<<Wei_Num);
    }
    Temp=Number;
      return Temp;
}

 二十、二进制转十进制

int BD_2To10(int a)
{
    int i, s = 0;
    int result = 0;
    for(i = 1; a != 0; i *= 2)
    {
        if (a % 10 > 1)
        {
            s = 1;
            break;
        }
        else
        {
            result += (a % 10) * i;
            a /= 10;
        }
     }
    return result;
}

二十一、二进制转八进制

int B_O_2To_8(int a)
{
    int i,j,k,s = 0;
    int p[30];
    int result = 0;
    for (i = 1; a != 0; i *= 2)
    {
        if (a % 10 > 1)
        {
            s = 1;
            break;
        }
        else
        {
            result += (a % 10) * i;
            a /= 10;
        }
    }

    for(j = 0; result != 0; j++)
    {
        p[j] = result % 8;
        result /= 8;
    }

    int OCT = 0;
    for (k = j - 1; k >= 0; k--){
        qDebug()<<p[k];
        OCT += p[k]*pow(10,k);
    }

    return OCT;
}

二十二、二进制转十六进制

int B_X_2To16(int a)
{
    int i, j, k, s = 0;
    char p[30];
    int result = 0;
    for (i = 1; a != 0; i *= 2){
        if (a % 10 > 1){
            s = 1;
            break;
        }
        else{
            result += (a % 10) * i;
            a /= 10;
        }
     }

     for (j = 0; result != 0; j++){
         p[j] = result % 16;
         result /= 16;

         if (p[j] >= 10){
             switch(p[j])
             {
             case 10: p[j] = 'A';
                 break;
             case 11: p[j] = 'B';
                 break;
             case 12: p[j] = 'C';
                 break;
             case 13: p[j] = 'D';
                 break;
             case 14: p[j] = 'E';
                 break;
             case 15: p[j] = 'F';
                 break;
             }
         }
         else
             p[j] += 48;
     }

     for (k = j - 1; k >= 0; k--){
         qDebug()<<p[k];
     }
         return 0;
}

二十三、八进制转二进制

int O_B_8To2(int a)
{
    int i, j, k, s = 0;
    int result = 0;
    int p[30];

    for(i = 1; a != 0; i *= 8)
    {
        if (a % 10 > 7)
        {
            s = 1;
            break;
        }
        else
        {
           result += (a % 10) * i;
           a /= 10;
        }
    }

    for(j = 0; result != 0; j++)
    {
        p[j] = result % 2;
        result /= 2;
    }

        for(k = j - 1; k >= 0; k--)
            qDebug()<<p[k];
       return 0;
}

二十四、八进制转十进制

int O_D_8To10(int a)
{
    int i, s = 0;
    int result = 0;
    for(i = 1; a != 0; i *= 8)
    {
       if(a % 10 > 7)
       {
           s = 1;
           break;
       }
       else
       {
           result += (a % 10) * i;
           a /= 10;
       }
    }

    return  result;
}

二十五、八进制转十六进制

void O_X(int a)
{
    int i, j, k, s = 0;
    char p[30];
    int result = 0;
    
    for (i = 1; a != 0; i *= 8)
    {
        if(a % 10 > 7)
        {
            s = 1;
            break;
        }
        else
       {
           result += (a % 10) * i;
           a /= 10;
       }
    }

    for (j = 0; result != 0; j++)
    {
        p[j] = result % 16;
        result = result / 16;
        if(p[j] < 10)
            p[j] += 48;
        else
        {
            switch(p[j])
            {
                case 10: p[j]='A';
                    break;
                case 11: p[j]='B';
                    break;
                case 12: p[j]='C';
                    break;
                case 13: p[j]='D';
                    break;
                case 14: p[j]='E';
                    break;
                case 15: p[j]='F';
                    break;
            }
        }
    }

    if(s == 1)
        printf("您的输入有误!请重新输入\n");
    else
    {
        printf("\n转换后的数为:");
        for (k = j - 1; k >= 0; k--)
            printf("%c",p[k]);

     printf("\n");
    }
}

二十六、 十六进制转换为十进制,二进制,八进制.

void X_D(char a[],int k)
{
    int i, j, s = 0;
    int result = 0;
    int b[50];
    for (i = 0; i < k; i++)
    {
        if(a[i] <= '9' && a[i] >= '1')
            b[i]=a[i]-48;
        else
        {
            switch(a[i])
            {
            case 'A': b[i] = 10;
                break;
            case 'B': b[i] = 11;
                break;
            case 'C': b[i] = 12;
                break;
            case 'D': b[i] = 13;
                break;
            case 'E': b[i] = 14;
                break;
            case 'F': b[i] = 15;
                break;
            case 'a': b[i] = 10;
                break;
            case 'b': b[i] = 11;
                break;
            case 'c': b[i] = 12;
                break;
            case 'd': b[i] = 13;
                break;
            case 'e': b[i] = 14;
               break;
            case 'f': b[i] = 15;
               break;
           default:  
                s = 1;
           }
        }
    }

    for (i = 1, j = k - 1; j >= 0; j--, i *=16)
        result+=b[j]*i;

    if(s == 1)
        printf("您的输入有误!请重新输入\n");
    else
        printf("\n转换后的数为:%d",result);
}


void X_B(char a[],int k)
{
    int i,j,s = 0;
    int result = 0;
    int b[50];
    int p[30];
  
    for (i = 0; i < k; i++)
    {
        if(a[i] <= '9' && a[i] >= '1')
            b[i]=a[i]-48;
        else
        {
            switch(a[i])
            {
            case 'A': b[i] = 10;
                break;
            case 'B': b[i] = 11;
                break;
            case 'C': b[i] = 12;
                break;
            case 'D': b[i] = 13;
                break;
            case 'E': b[i] = 14;
                break;
            case 'F': b[i] = 15;
                break;
            case 'a': b[i] = 10;
                break;
            case 'b': b[i] = 11;
                break;
            case 'c': b[i] = 12;
                break;
            case 'd': b[i] = 13;
                break;
            case 'e': b[i] = 14;
               break;
            case 'f': b[i] = 15;
               break;
           default:  
                s = 1;
           }
        }
     }

     for (i = 1, j = k - 1; j >= 0; j--, i *=16)
          result+=b[j]*i;

     for (j = 0; result != 0; j++)
     {
          p[j] = result % 2;
          result /= 2;
     }

    if(s == 1)
         printf("您的输入有误!请重新输入\n");
    else
    {
         printf("\n转换后的数为:");
         for (k = j - 1; k >= 0; k--)
             printf("%d",p[k]);

         printf("\n");
    }
}

void X_O(char a[],int k)
{
    int i,j,s = 0;
    int result = 0;
    int b[30];
    int p[30];
 
    for (i = 0; i < k; i++)
    {
        if(a[i] <= '9' && a[i] >= '1')
            b[i]=a[i]-48;
        else
        {
            switch(a[i])
            {
            case 'A': b[i] = 10;
                break;
            case 'B': b[i] = 11;
                break;
            case 'C': b[i] = 12;
                break;
            case 'D': b[i] = 13;
                break;
            case 'E': b[i] = 14;
                break;
            case 'F': b[i] = 15;
                break;
            case 'a': b[i] = 10;
                break;
            case 'b': b[i] = 11;
                break;
            case 'c': b[i] = 12;
                break;
            case 'd': b[i] = 13;
                break;
            case 'e': b[i] = 14;
               break;
            case 'f': b[i] = 15;
               break;
           default:  
                s = 1;
           }
        }
    }
    for (i = 1, j = k - 1; j >= 0; j--, i *=16)
         result+=b[j]*i;

    for (j = 0; result != 0; j++)
    {
         p[j] = result % 8;
         result /= 8;
    }

    if(s == 1)
         printf("您的输入有误!请重新输入\n");
    else
    {
         printf("\n转换后的数为:");
         for (k = j - 1; k >= 0; k--)
             printf("%d",p[k]);

         printf("\n");
    }
}

二十七、十进制转换为二进制,八进制,十六进制.

void D_B(int a)
{
    int j, k;
    int p[30];
 
    for (j = 0; a != 0; j++)
    {
        p[j] = a % 2;
        a /= 2;
    }

    printf("\n转换后的数为:");
    for(k = j - 1; k >= 0; k--)
        printf("%d", p[k]);
 
    printf("\n");
}

void D_O(int a)
{
    int j, k;
    int p[30];
 
    for (j = 0; a != 0; j++)
    {
        p[j] = a % 8;
        a /= 8;
    }

    printf("\n转换后的数为:");
    for(k = j - 1; k >= 0; k--)
        printf("%d", p[k]);
 
    printf("\n");
}

void D_X(int a)
{
    int j,k;
    int p[30];

    for (j = 0; a != 0; j++)
    {
        p[j] = a % 16;
        a /= 16;
       
       if(p[j] < 10)
           p[j]+=48;
       else
       {
           switch(p[j])
           {
           case 10: p[j] = 'A';
               break;
           case 11: p[j] = 'B';
               break;
           case 12: p[j]='C';
               break;
           case 13: p[j]='D';
               break;
           case 14: p[j]='E';
               break;
           case 15: p[j]='F';
               break;
          }
       }
    }

    printf("\n转换后的数为:");
    for (k = j - 1; k >= 0; k--)
        printf("%c",p[k]);

    printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gallagher_SF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值