954,480 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

hex string to decimal

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?

MrNoob
Posting Whiz in Training
218 posts since May 2009
Reputation Points: 34
Solved Threads: 7
 

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.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

thanks i will try

MrNoob
Posting Whiz in Training
218 posts since May 2009
Reputation Points: 34
Solved Threads: 7
 

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.

MrNoob
Posting Whiz in Training
218 posts since May 2009
Reputation Points: 34
Solved Threads: 7
 

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();
}
MrNoob
Posting Whiz in Training
218 posts since May 2009
Reputation Points: 34
Solved Threads: 7
 

>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.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

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

MrNoob
Posting Whiz in Training
218 posts since May 2009
Reputation Points: 34
Solved Threads: 7
 

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;
}
MrNoob
Posting Whiz in Training
218 posts since May 2009
Reputation Points: 34
Solved Threads: 7
 

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 () 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.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

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 ?

MrNoob
Posting Whiz in Training
218 posts since May 2009
Reputation Points: 34
Solved Threads: 7
 

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".

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You