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?

Recommended Answers

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.