在前文《再议C语言将十六进制字符串转成十进制整数》中 @大致 童鞋帮忙提了一个思路:直接将指针p
读取的十六进制字符串中的单个字符转换后的结果保存在iResult
中,而不是保存在指针p指向的内存中。这样思路更为简洁,下面是具体的两个实现程序。
1 从高位到低位单个字符转换
正向转换时,提前判断出字符串中部分非法字符,然后根据+
、-
、0x
、0X
这四个特殊字符(串)对指针变量p进行特殊处理。
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
57
58
59
60
61
62
63
64
65 | #include <stdio.h>
#include <string.h>
/**
* @FileName HexStr2Integer.c
* @author vfhky 2015.05.30 https://typecodes.com/cseries/simplifychexstrtoint.html
* @param [in]HexStr 十六进制字符串(例如"eE2"、"Fa1"、"2011"、"-eE2"、"+eE2"等)
* @return -1:字符串为空; -2:字符串中包含非十六进制的字符; 其它:转换后的十进制整数
*/
int HexStr2Integer( char * HexStr )
{
int iResult = 0, iFlag = 1;
//判断字符串是否合法
if( NULL == HexStr || ( *HexStr == '+' && *(HexStr+1) == '\0' ) || ( *HexStr == '-' && *(HexStr+1) == '\0' )
|| ( *HexStr == 0x30 && *(HexStr+1) == 0x58 && *(HexStr+2) == '\0' )
|| ( *HexStr == 0x30 && *(HexStr+1) == 0x78 && *(HexStr+2) == '\0' ) )
{
return -1;
}
//指针变量p指向字符串的首位
char * p = HexStr;
//对以"+"、"-"号开头的十六进制字符串的处理
if ( '-' == *p || '+' == *p )
{
if( *p == '-' )
iFlag = -1;
++p;
}
//对"0x"或者"0X"开头的十六进制字符的处理
else if( ( *p == 0x30 && *(p+1) == 0x58 ) || ( *p == 0x30 && *(p+1) == 0x78 ) )
{
p += 2;
}
while( *p != '\0' )
{
if ( *p >= 48 && *p <= 57 )
iResult = ( *p - 48 )+ ( iResult<<4 );
else if ( *p >= 65 && *p <= 70 )
iResult = ( *p - 65 + 10 )+ ( iResult<<4 );
else if ( *p >= 97 && *p <= 102 )
iResult = ( *p - 97 + 10 )+ ( iResult<<4 );
else
return -2;
++p;
}
return iFlag*iResult;
}
int main( int argc, char * argv[] )
{
char cHexString[200+1];
while(1)
{
memset( cHexString, 0x00, sizeof(cHexString) );
printf( "Please input a HexString with length less than 200:\n" );
scanf( "%s", cHexString );
printf( "---->[%d]\n", HexStr2Integer(cHexString) );
}
return 0;
}
|
同样使用GCC编译命令gcc HexStr2Integer.c -o HexStr2Integer
,然后输入测试用的十六进制的字符串"eE2"、"Fa1"、"2011"、"-eE2"、"+eE2"分别转换成了对应的十进制整数:3810、4001、8209、-3810、3810。
2 从低位到高位单个字符转换
逆向转换时,需要注意while
循环中通过对+
、-
、0x
、0X
这四个特殊字符(串)的判断出非法字符。
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 | #include <stdio.h>
#include <string.h>
/**
* @FileName HexStr2Integer2.c
* @author vfhky 2015.05.30 https://typecodes.com/cseries/simplifychexstrtoint.html
* @param [in]HexStr 十六进制字符串(例如"eE2"、"Fa1"、"2011"、"-eE2"、"+eE2"等)
* @return -1:字符串为空; -2:字符串中包含非十六进制的字符; 其它:转换后的十进制整数
*/
int HexStr2Integer2( char * HexStr )
{
int iResult = 0, iCycle = 1, iFlag = 1;
//判断字符串是否合法
if( !strlen( HexStr ) )
{
return -1;
}
//指针变量p指向字符串的末尾
char * p = HexStr + strlen( HexStr );
while( (--p+1) != HexStr )
{
if ( *p >= '0' && *p <= '9' )
iResult += ( *p - '0' )*iCycle;
else if ( *p >= 'A' && *p <= 'F' )
iResult += ( *p - 'A' + 10 )*iCycle;
else if ( *p >= 'a' && *p <= 'f' )
iResult += ( *p - 'a' + 10 )*iCycle;
else if ( ( '+' == *p && ( p == HexStr + 1 ) )
|| ( 'x' == *p && '0' == *( p - 1 ) && ( p == HexStr + 1 ) )
|| ( 'X' == *p && '0' == *( p - 1 ) && ( p == HexStr + 1 ) ) )
break;
else if ( '-' == *p && p == HexStr )
iFlag = -1;
else
return -2;
iCycle <<= 4;
}
return iFlag*iResult;
}
int main( int argc, char * argv[] )
{
char cHexString[200+1];
while(1)
{
memset( cHexString, 0x00, sizeof(cHexString) );
printf( "Please input a HexString with length less than 200:\n" );
scanf( "%s", cHexString );
printf( "---->[%d]\n", HexStr2Integer2(cHexString) );
}
return 0;
}
|
同样,使用GCC编译后,输入十六进制字符串数据进行测试,结果如下图所示:
Comments »