Easily. Why do work which the library will do for you?
#include <limits.h>
#include <stdlib.h>
unsigned int htoi(char *txt)
{
unsigned long tmp=strtoul(txt, 0, 16);
if (tmp>UINT_MAX) return UINT_MAX;
return tmp;
}
but here htoi(8eeeeeeeeeeeeeeeeeeeeeee)==-1
this seems htoi(8eeeeeeeeeeeeeeeeeeeeeee)== INT_MAX
unsigned int htoi(char *txt)
{unsigned long tmp=strtoul(txt, 0, 16);
if (tmp>=UINT_MAX)
return INT_MAX;
return tmp;
}
Shorter, sweeter, doesn't waste value space on negative numbers which
you don't parse anyway, doesn't invoke undefined behaviour on overflow,
and is portable no matter what your character set it. Feel free.
Richard
but my htoi2 seems 2*faster than library htoi()
C:>2_7_c
test is ok
Differenza libreria =6.000000 s
Differenza mia =2.000000 s
C:>2_7_c
test is ok
Differenza libreria =6.000000 s
Differenza mia =3.000000 s
C:>2_7_c
test is ok
Differenza libreria =6.000000 s
Differenza mia =3.000000 s
C:>2_7_c
test is ok
Differenza libreria =6.000000 s
Differenza mia =3.000000 s
C:>2_7_c
test is ok
Differenza libreria =6.000000 s
Differenza mia =3.000000 s
#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>
char* riempi_hex(char* a, int lunghezza)
{static char ary[]="0123456789abcdefABCDEF";
int i, j, lungh;
assert( a!=NULL && lunghezza>13 );
lungh = rand() % 12;
for( j=0; j<lungh; ++j )
a[j]=ary[ rand() % 21 ];
a[j]=0;
return a;
}
unsigned int htoi(char *txt)
{unsigned long tmp=strtoul(txt, 0, 16);
if (tmp>=UINT_MAX)
return INT_MAX;
return tmp;
}
char* volte1(void)
{static char xd[512] = {16};
xd['0']= 0; xd['1']= 1; xd['2']= 2; xd['3']= 3; xd['4']= 4; xd['5']=
5;
xd['6']= 6; xd['7']= 7; xd['8']= 8; xd['9']= 9;
xd['a']=10; xd['b']=11; xd['c']=12; xd['d']=13; xd['e']=14;
xd['f']=15;
xd['A']=10; xd['B']=11; xd['C']=12; xd['D']=13; xd['E']=14;
xd['F']=15;
return xd;
}
int ci_siamo_o_no(void)
{if('9'>= 512 ||
'a'>= 512 || 'b'>= 512 || 'c'>= 512 || 'd'>= 512 || 'e'>= 512 ||
'f'>= 512 ||
'A'>= 512 || 'B'>= 512 || 'C'>= 512 || 'D'>= 512 || 'E'>= 512 ||
'F'>= 512
) return 0;
return 1;
}
int htoi2(char* s)
{unsigned i=0, n=0, d, h;
static char *p=0;
char c;
assert(s!=NULL);
if(p==0) p=volte1();
while( (c=s
)==' ' || c=='\t' || c=='\n' )
i++;
if( c=='0' && ( s[i+1]=='x' || s[i+1]=='X') )
{i+=2; c=s;}
while(1)
{d= c>0 && (unsigned) c < 512u ? p[c]: 16;
if(d==16)
break;
if( n>(UINT_MAX/16) || ( h=(n*16) )> UINT_MAX - d )
{n= ((int)n)>0 ? INT_MAX : INT_MIN; break;}
n= h + d;
c=s[++i];
}
return (int) n;
}
int main(void)
{char b[30]={0};
int c, ch, j;
time_t x, y;
c=ci_siamo_o_no();
assert(c==1);
srand(time(0));
for(j=0; j<700000; ++j)
{riempi_hex(b, 30);
c=htoi(b); ch=htoi2(b);
if(c!=ch && c-ch!=-1)
{printf("\nPartenza=%s\n",b);
printf("Arrivo =%d\n", c );
printf("Arrivo1 =%d\nTest fails \n", ch);
}
}
printf("test is ok \n");
x=time(0);
for(j=0; j<7000000; ++j)
{riempi_hex(b, 30);
c=htoi(b);
if(c==9999999)
{printf("\nPartenza=%s\n",b);
printf("Arrivo =%d\n", c );
}
}
y=time(0);
printf("Differenza libreria =%f s \n", difftime(y,x) );
x=time(0);
for(j=0; j<7000000; ++j)
{riempi_hex(b, 30);
c=htoi2(b);
if(c==9999999)
{printf("\nPartenza=%s\n",b);
printf("Arrivo =%d\n", c );
}
}
y=time(0);
printf("Differenza mia =%f s \n", difftime(y,x) );
return 0;
}