i m trying to code htoi function in chapter 2.3 for K&R but problem i dunno where to start should i first read all string then after that change each character to its decimal and then add them ? or any better ideas?

## All 10 Replies

Treat it as a variation of K&R's atoi. You should already know that you can step through the string and add the characters like so:

``result = radix * result + digit;``

If radix is 16, you're converting a hexadecimal value. Now all you need to do is figure out how to convert the A-F digits of a hexadecimal number to 10-15 for the digit value in the snippet above. One way is an indexed lookup. First you find the character in a list of digits, then the index tells you its value:

``````#include <stdio.h>

int main ( void )
{
const char *digits = "0123456789ABCDEF";
size_t i;

for ( i = 0; digits[i] != '\0'; i++ )
printf ( "%c = %d\n", digits[i], i );

return 0;
}``````

See what you can come up with using those hints.

thanks i will try

but is there a equation to change the characters hex to decimal because sometimes if a string got F or A it will just change that to its ascii value.

i think i made it but its not so compact just bunch of test will work only from A to F but if you add like AA or 2 FF or others wont work but i hope i will fix it l8er

``````#include <stdio.h>
int htoi(char *HString)
{
int i;
int n=0,n2;
for(i=0;HString[i]!=0;i++) {
if(HString[i]=='A'|| HString[i]=='a')
n+=10;
if(HString[i]=='B' || HString[i] == 'b')
n+=11;
if(HString[i]=='C' || HString[i]=='c')
n+=12;
if(HString[i]=='D' || HString[i]=='d')
n+=13;
if(HString[i]=='E' || HString[i]=='e')
n+=14;
if(HString[i]=='F' || HString[i]=='f')
n+=15;
else if(HString[i]<='0' && HString[i]>='9')
n+=HString[i];
}
return n;
}
int main(void)
{
char name[]="F";
int x;
x=htoi(name);
printf("%d",x);
return getchar();
}``````

>but is there a equation to change the characters hex to decimal because
>sometimes if a string got F or A it will just change that to its ascii value.

There is a compact and easy way to do what you want. You can find details on how to do it here.

p.s. Thanks for ignoring me. I won't waste my time with you anymore. Figure it out yourself.

srry i didnt notice your talking about indexed search i think i know how to do it now...

fixed it

``````unsigned int htoi(char *HString)
{
int i,Hexo,n=0;
for(i=0;HString[i]!=0;i++) {
if(HString[i]<='A' && HString[i]>='F') {
Hexo= HString[i] - '0';
n = 16 * n + Hexo;
}
else if(HString[i] >='a' && HString[i] <='f') {
Hexo= HString[i] -'a' + 10;
n = 16 * n + Hexo;
}
else if(HString[i] >='A' && HString[i] <='F') {
Hexo= HString[i] -'A' + 10;
n = 16 * n + Hexo;
}
}
return n;
}``````

I see two glaring problems with your code.

First, it's very ASCII-centric. C only guarantees that the decimal digits will be adjacent in the character set, so while `(c >= 0 && c <= '9')` is required to work as expected, `(c >= 'a' && c <= 'f')` doesn't have to. And subtracting 'a' from the value could have wildly incorrect results on non-ASCII character sets, where non-alphabet characters could be mixed in with the alphabet.

Second, it's redundant. You don't have to duplicate the code for different casing. The standard library (<ctype.h>) offers both toupper and tolower which will convert a character to the upper and lower case formats, respectively, and do nothing with a character that has no such conversion.

Compare and contrast your code with mine:

``````#include <ctype.h>

int hex_value ( char ch )
{
const char *digits = "0123456789ABCDEF";
int i;

for ( i = 0; digits[i] != '\0'; i++ ) {
if ( toupper ( (unsigned char)ch ) == digits[i] )
break;
}

return digits[i] != '\0' ? i : -1;
}

unsigned htoi ( const char *s )
{
unsigned result = 0;

while ( *s != '\0' )
result = 16 * result + hex_value ( *s++ );

return result;
}``````

Note that I left out error checking intentionally to clarify the logic. An invalid string won't give you sensical results.

commented: *whew* My 'playing along at home' version looked very similar. I take that as a Good Thing. +20

nice code mate yah i also wanted to ask i see alot people doing while(*s!=0) that mean it will keep running till it reach 0 ?

Strings in C always end with a '\0' character (which also happens to have the integral value 0). When I read or write `while ( *s != '\0' )` , my mind thinks "while not at the end of the string".

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.