0

I've written this semi-htoi function in c that takes a hexadecimal string and turns it to hexadecimal int.

*if I correct this, I can turn it to real htoi function

#include<stdio.h>

int main(void)
{
char c;
int a = 0x0;
//a += 1;if do this, we have added 1 to 0 hexadecimal
while((c = getchar()) != '`')
{
    if((c >= '0') && (c <= '9')){
        a = a * 16 + (c - '0');
        printf("a is:%x c:%c\n", a, c);
    }
    else if((c >= 'a') && (c <= 'f')){
        a = a * 16 + c;
        printf("a is:%x c:%c\n", a, c);
    }
    else if((c >= 'A') && (c <= 'F')){
        a = a * 16 + c;
        printf("a is:%x c:%c\n", a, c);
    }
}
printf("\nyour hexa number is:\n%hhx\n", a);
return 0;
}

but it doesn't work, while if I change a = a * 16 + c to a = a * 10 + c

and int a = 0x0 to int a = 0 it work as atoi

arianpress
  • 456
  • 1
  • 6
  • 16

1 Answers1

2

One problem is your printf() statement:

printf("\nyour hexa number is:\n%hhx\n", a);

The %hhx conversion specification says 'treat the argument as an unsigned char'. That isn't what you want. You should use:

printf("\nyour hexa number is: %x\n", a);

(I replaced the newline after the colon with a space — the output will look better that way. It isn't a necessary change.)

Another problem is the conversion code for hexadecimal characters, as documented in the comments.

Yet another problem is that getchar() returns an int and not a char. See while ((c = getc(file)) != EOF) loop won't stop executing for more details. Also, your loop should terminate on EOF and should probably terminate on newline too. You stop on a back-tick without generating an error; you ignore other non-hexadecimal characters.

You should also consider using isdigit() and isxdigit() and maybe tolower() or toupper() from <ctype.h>. The a..f check works on all ASCII and EBCDIC code sets, but if you were testing a much bigger range (e.g. a..i), then your comparison would not be reliable for EBCDIC.

Putting all the suggestions together, I would produce something more like this:

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int c;
    int a = 0x0;
    while ((c = getchar()) != '`' && c != EOF && c != '\n')
    {
        if (isdigit(c))
        {
            a = a * 16 + (c - '0');
            printf("a is: %x c:%c\n", a, c);
        }
        else if (isxdigit(c))
        {
            a = a * 16 + (toupper(c) - 'A' + 10);
            printf("a is: %x c:%c\n", a, c);
        }
        else
        {
            printf("'%c' is not a hexadecimal digit\n", c);
            break;
        }
    }
    printf("\nYour hexadecimal number is: %x\n", a);
    return 0;
}

I'd be very tempted to remove the test for back-quote and let the 'not a hexadecimal digit' code deal with it.

Sample runs of hx53 — created from hx53.c and using Bash here strings to provide the input:

$ hx53 <<< 'a32419fC'
a is: a c:a
a is: a3 c:3
a is: a32 c:2
a is: a324 c:4
a is: a3241 c:1
a is: a32419 c:9
a is: a32419f c:f
a is: a32419fc c:C

Your hexadecimal number is: a32419fc
$ hx53 <<< 'a32419`fC'
a is: a c:a
a is: a3 c:3
a is: a32 c:2
a is: a324 c:4
a is: a3241 c:1
a is: a32419 c:9

Your hexadecimal number is: a32419
$ hx53 <<< 'a32419XfC'
a is: a c:a
a is: a3 c:3
a is: a32 c:2
a is: a324 c:4
a is: a3241 c:1
a is: a32419 c:9
'X' is not a hexadecimal digit

Your hexadecimal number is: a32419
$
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278