0

im writing a code for converting a number to hexadecimal and im getting a random numbers as result. at first i succeed to convert the number but it was in a reversed order (the first mod needs to be the last number or letter). the code is a part (for cases of %x) from a big project that is kind of implementation of sprintf (so sprintf or printf are not allowed obviously). so the buffer is for composing a string without any placeholders. thank u in advance.

here's my code:

int num = *(int*)ptrs[counter];
int tempnum=num;
int mod=0;
int length =0;
for(int i=0;tempnum !=0;i++)
{
    length++;
    tempnum /= 16;
}
int array[length];
for(int i= length; i>0;i--)
{
    mod = num%16;
    num = num/16;
    array[i] = mod;
}
for(int i=0;i<length;i++)
{
    if(array[i]<10)
        *buffer = array[i]+ '0';
    else
        *buffer = array[i] -10 + 'a';
    buffer++;
}

marksman123
  • 389
  • 2
  • 11
  • I guess you mean `array[i] + 'a'` – Cheatah May 23 '20 at 17:39
  • You should create a [mre] – klutt May 23 '20 at 17:40
  • 1
    What is `*buffer = array[i] + '87';` doing? I believe it should be `*buffer = array[i] - 10 + 'a';` or `*buffer = array[i] - 10 + 'A';` – isrnick May 23 '20 at 17:42
  • Yeah, but even then I would be wrong, see @isrnick comment. I didn't bother to look any further than the first error I spotted. – Cheatah May 23 '20 at 17:45
  • @isrnick yes, that's what i tried to do (only your accurate and im not). but still in the second convertion (where it shouldve been b if my number is 123 for example), it gives me some random char. – marksman123 May 23 '20 at 17:46
  • 1
    This for is wrong: `for(int i= length; i>0;i--)`, it should be `for(int i= length-1; i>=0;i--)` – isrnick May 23 '20 at 17:51
  • When `num == 0`, `int array[length];` is UB. – chux - Reinstate Monica May 23 '20 at 18:26
  • "for composing a string" --> code never sets the _null character_ – chux - Reinstate Monica May 23 '20 at 18:28
  • 1
    Many problems with this code. Sample code to form a string of any base [TO_BASE(some_unsigned, base)](https://stackoverflow.com/a/34641674/2410359). – chux - Reinstate Monica May 23 '20 at 18:34
  • marksman123 when `num == -10`, what result do you expect in `buffer[]`? – chux - Reinstate Monica May 23 '20 at 18:41
  • @chux-ReinstateMonica its a small portion from the code. in the whole code it does set a null character, and the code is far from being done.. i know there is a lot to fix(such as handling with negative numbers ) . i just wanted to know if im missing something with this specific conversion of `%x` . and on top of that im only a freshman at university (computer science degree of course), so my code will be a little bit far from perfect :). and your notes are extremly helpful, thank you very much for that. – marksman123 May 23 '20 at 18:49
  • 1
    marksman123 Note that `"%x"` is for `unsigned`, not `int`. – chux - Reinstate Monica May 23 '20 at 19:33

3 Answers3

2

The for loop of calculating array[i] should change to:

    for(int i = length-1; i>=0;i--) // i from (length - 1) to 0 instead of from length to 1.
    {
        mod = num%16;
        num = num/16;
        array[i] = mod;
    }

You do not need to change the buffer pointer. You can use:

    for(int i=0;i<length;i++)
    {
        if(array[i]<10)
            buffer[i] = array[i]+ '0';
        else
            buffer[i] = array[i] + 55;
    }

then do not forget at the null character at the end of buffer:

buffer[length] = '\0';

I do not see the declaration of buffer in your code, so i propose the solution above for the declaration:

 char buffer[length+1];
Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • If this is an implementation of printf it may be convenient to increment buffer, as the string may contain more than just the hexadecimal integer, and without incrementing the buffer it would need a counter variable to keep track of the characters in the string. Also it may not be the end of the string right after the number, as more text may be added. – isrnick May 23 '20 at 18:04
  • @isrnick I mentioned in my answer that i propose the solution for the declaration of `buffer` as `char buffer[length+1];` because i do not see any declaration of `buffer` in the OP's code. – Hitokiri May 23 '20 at 18:18
  • 1
    Note code will fail to provide correct results when `num < 0`. – chux - Reinstate Monica May 23 '20 at 18:20
  • @chux-ReinstateMonica Yes, it's better if we use `num = abs(num)` or exit the rest of code `if(num<0)` ? – Hitokiri May 23 '20 at 18:22
  • Note that `abs(INT_MIN)` is UB. With OP's goal, perhaps use `unsigned`? – chux - Reinstate Monica May 23 '20 at 18:23
  • @chux-ReinstateMonica it depends on what OP want. I thinks `if(num<0) {num = -num; //or exit}` is OK ? – Hitokiri May 23 '20 at 18:28
  • 1
    When `num == INT_MIN`, what value do you think `num` has after `if(num<0) {num = -num;}`? IAC, `-INT_MIN` is UB. – chux - Reinstate Monica May 23 '20 at 18:30
  • 1
    @chux-ReinstateMonica i got it. it seems that `unsigned` is better. Thank for your comment – Hitokiri May 23 '20 at 18:32
1
for(int i= length; i>0;i--)
                {
                    mod = num%16;
                    num = num/16;
                    array[i] = mod;
                }

mistakes at array[i] to array[i-1].

buffer = array[i] + '87';

I suggest you use:

buffer = array[i]-10 + 'a';
0
printf("%i", (int)[any hexadecimal number]);

would print the integer form of this '[any hexadecimal number]' number

person the human
  • 345
  • 4
  • 15