Converting hexadecimal digital to integer

I have the code below to convert hex digits to integer.But I want a char with all possible digits e.g. char s[]="0123456789abcdef"; and calculate the integer values dynamically: s[2] = 2 or s[12] = 12 and then calculate hexdigit.How this can be done at best?

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
int htoi(char s[])
{
    int hexdigit,i,inhex,n;
    i = 0;
    if( s[i] == '0')
    {
        ++i;
        if(s[i] == 'x' || s[i] == 'X')
            ++i;
    }
    
    n = 0;
    inhex = YES;

    for(;inhex==YES;++i)
    {
        if(s[i] >='0' && s[i] <='9')
            hexdigit= s[i] - '0';
        else if(s[i] >='a' && s[i] <='f')
            hexdigit= s[i] -'a' + 10;
        else if(s[i] >='A' && s[i] <='F')
            hexdigit= s[i] -'A' + 10;
        else
            inhex = NO;
        
        if(inhex == YES)
            n = 16 * n + hexdigit;
    }
    return n;
}
Could you rephrase your question? I can not understand what you are asking. What do you mean by "calcuate integer values dynamically"?
Instead of hexdigit = s[i] - '0' or s[i] - 'a' + 10 => n = 16* n+hexdigit
s[0] = 0, s[1] = 1 ... s[15] = 15 (using char s[] defined above in my question)
and then n = 16* n + s[i]
Last edited on
Instead of hexdigit = s[i] - '0' or s[i] - 'a' + 10 => n = 16* n+hexdigit

Here s[i] is an individual character from the hex number you are converting

s[0] = 0, s[1] = 1 ... s[15] = 15

But here it seems like you are trying to express something like s[ s[i] ]. I would recommend creating a seperate array if you would like to lookup values, and do something like other_array[ s[i] ]. This would require an array that has 255 locations, because char variables range from 0 to 255. But there is an even better solution than that, and it is what you are already doing abstracted to a function.

1
2
3
4
5
6
7
8
9
10
11
12
//return -1 if the char is not a hex digit
//otherwise, returns a value in [0, 15]
int int_hex_digit_from_char(char ch) {
    int hexdigit = -1;
    if(ch >= '0' && ch <= '9')
        hexdigit = ch - '0';
    else if(ch >= 'a' && ch <= 'f')
        hexdigit = ch - 'a' + 10;
    else if(ch >= 'A' && ch <= 'F')
        hexdigit = ch - 'A' + 10;
    return hexdigit;
}


The function would be used instead of some other array in something like, int hexdigit = int_hex_digit_from_char( s[i] ); followed by an if statement checking for -1.

The function isxdigit may interest you, because you could call this to validate that a char is a hex digit.
http://www.cplusplus.com/reference/cctype/isxdigit/
Last edited on
You are Right but what I want is not to be addicted to specific numeral system (+ 10)
How would it look like with something like s[s[i]]?
What I was trying to explain briefly about s[ s[i] ] in my last post, is that it makes no sense. Think about it. s[i] is a hex char from a number that you are converting which is then used as an index to the same s array. s[ char that you are converting ] just does not make any logical sense. Which is why I recommended another array, other_array. If you really did want to use another array to store the values, you would need to initialize the locations '0' to '9' with 0 to 9, 'a' to 'f' and 'A' to 'F' with 10 to 15, and all the other locations with some error value. I can assure you that using another array is a bad road to travel down for this problem. A function handles this same mapping of inputs to outputs in a much more readable way than the code for this other array would.

Not being stuck on a specific numeral system is a bit unrelated to this char to hex digit conversion. 'a' should always have a value of 1010, 128, 10102, etc.. Therefore this hex digit conversion function is correct when it reports 1010 for the input of 'a'. It would also be correct if it reported 128. Because 1010 and 128 are equivalent. This kind of conversion is happening very frequently within a computer. All numbers are ultimately represented with binary base in memory. When C++ has to display this binary representation in base 10, somewhere down the line is a function that does the math to figure out what ASCII digits need to be displayed.

In C++ it is possible to convert how integers are displayed to a few different bases. http://www.cplusplus.com/reference/ios/oct/

It is also possible to specify literal numbers in bases other than 10.
int sixteen = 0x10; //0x is the prefix to use hexadecimal
Last edited on
If you can use C++11 features, you could try to do it like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>     // use std::string, std::stoi


int htoi(char s[]) // int htoi(char* s) works equally well and is a bit more correct
{
	int sum = 0;
	std::string theInputString(s);
	for(int index=0; index<theInputString.length();index++)
	{
		// Here you convert the hex value to base 10 and add it to the previous values.
		sum = sum + std::stoi(std::string(1, theInputString[index]), nullptr, 16);
	}
	return sum;
}

int main()
{
    std::cout << htoi("012345") << std::endl;
    std::cout << htoi("6789") << std::endl;
    std::cout << htoi("abcd") << std::endl;
    std::cout << htoi("0123456789abcd") << std::endl;
    return 0;
}


However, given the name of your function I would expect that this is closer to what you need.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>     // use std::string, std::stoi


int htoi(char s[]) // int htoi(char* s) works equally well and is a bit more correct
{
	std::string theInputString(s);
	// Here you convert the hex value to base 10.
	return std::stoi(theInputString, nullptr, 16);
}

int main()
{
    std::cout << htoi("012345") << std::endl;
    std::cout << htoi("6789") << std::endl;
    std::cout << htoi("abcd") << std::endl;
    // make sure you don't enter anything larger than MAXINT
    return 0;
}


Also, note that you are not really passing an array s as the argument, you are actually passing a char* s that points to an array.

Kind regards, Nico

http://www.cplusplus.com/reference/string/stoi/
Last edited on
Topic archived. No new replies allowed.