TypeCodes

C语言将十六进制字符串转成十进制整数

C/C++处理十六进制文件中的报文内容时,经常会遇到先读取报文头中的长度(例如"E2"、"1F"、"-eE2"等等),再读取报文体中的内容的情况。那么就需要把报文头中表示长度的十六进制字符串转换成十进制的整形数据。

转换方法有两种,一种是正向从字符串低位到高位依次转换,另一种是逆向从字符串高位到低位依次转换。原理都是利用指针变量依次指向十六进制字符串中的单个字符,然后通过ASCII码表转换成对应的整数。考虑到十进制的字符串中可能会出现正负号,即转换后可能出现负整数,所以增加了对这种情况的处理。下面是两种方法的具体代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/** 
 * 将十六进制字符串转十进制数函数[从低位到高位单个字符转换]
 * @author  vfhky 2014.10.24 https://typecodes.com
 * @param   [in]    HexStr 十六进制字符串(例如"eE2"、"Fa1"、"2011"、"-eE2"、"+eE2"等) 
 * @return  -1:字符串为空; -2:字符串中包含非十六进制的字符; 其它:对应的十进制整数  
 */  
int HexStr2Integer1( char * HexStr )
{
    int iResult, iCycle, iHexStrLen;
    iResult = 0;
    iCycle = 1;
    iHexStrLen = 0;
    //正负数的标识,1正 -1负
    int iFlag = 1;

    //初始化指针变量p(指向十六进制字符串的首地址)
    char * p = HexStr;

    //获取十六进制字符串的长度
    while( *p != 0x00 )
        p++;
    iHexStrLen = p - HexStr;

    //判断字符串是否合法
    if( iHexStrLen == 0 || ( *HexStr == '+' && iHexStrLen == 1 ) || ( *HexStr == '-' && iHexStrLen == 1 ) )
        return -1;

    //长度去掉正负号,并设置字符数的标识
    if( ( *HexStr == '+' ) || ( *HexStr == '-' ) )
    {
        --iHexStrLen;
        p = HexStr + 1;
        if( *HexStr == '-' )
            iFlag = -1;
    }
    else p = HexStr;

    //循环将每个十六进制的字符转换成对应的十进制整数
    while( iCycle <= iHexStrLen )
    {
        if( ( *p >= 48 ) && ( *p <= 57 ) )
           *p -= 48;
        else if( ( *p >= 65 ) && ( *p <= 70 ) )
           *p -= 65 - 10;
        else if( ( *p >= 97 ) && ( *p <= 102 ) )
           *p -= 97 - 10;
        else
            return -2;
       iResult = *p + iResult*16;
       ++iCycle;
       ++p;
    }

    //返回转换后的整数
    return iFlag*iResult;
}

如下图所示,用GCC编译(gcc hextointeger.c -o hextointeger)测试程序并执行,结果将三个测试用的十六进制的字符串"eE2"、"Fa1"、"2011"、"-eE2"、"+eE2"分别转换成了对应的十进制整数:3810、4001、8209、-3810、3810。

十六进制字符串转成十进制整数

用下面逆向从字符串高位到低位依次转换的方法结果也是一样的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/** 
 * 将十六进制字符串转十进制数函数[从高位到低位单个字符转换]
 * @author  vfhky 2014.10.24 https://typecodes.com
 * @param   [in]    HexStr 十六进制字符串(例如"eE2"、"Fa1"、"2011"、"-eE2"、"+eE2"等) 
 * @return  -1:字符串为空; -2:字符串中包含非十六进制的字符; 其它:对应的十进制整数  
 */
int HexStr2Integer2( char * HexStr )
{
    int iResult, iCycle, iHexStrLen;
    iResult = 0;
    iCycle = 1;
    iHexStrLen = 0;
    //正负数的标识,1正 -1负
    int iFlag = 1;

    //初始化指针变量p(指向十六进制字符串的首地址)
    char * p = HexStr;

    //获取十六进制字符串的长度
    while( *p != 0x00 )
        p++;
    iHexStrLen = p - HexStr;

    //判断字符串是否合法
    if( iHexStrLen == 0 || ( *HexStr == '+' && iHexStrLen == 1 ) || ( *HexStr == '-' && iHexStrLen == 1 ) )
        return -1;

    //长度去掉正负号,并设置字符数的标识
    if( ( *HexStr == '+' ) || ( *HexStr == '-' ) )
    {
        --iHexStrLen;
        if( *HexStr == '-' )
            iFlag = -1;
    }

    //循环将每个十六进制的字符转换成对应的十进制整数
    while( iHexStrLen > 0 )
    {
        --p;
        if( ( *p >= 48 ) && ( *p <= 57 ) )
           *p -= 48;
        else if( ( *p >= 65 ) && ( *p <= 70 ) )
           *p -= 65 - 10;
        else if( ( *p >= 97 ) && ( *p <= 102 ) )
           *p -= 97 - 10;
        else
            return -2;
       iResult += *p*iCycle;
       iCycle *= 16;
       --iHexStrLen;
    }

    //返回转换后的整数
    return iFlag*iResult;
}
打赏支持

Comments »