Convert Function in Hexadecimal or Octal base

87 Views Asked by At

I used to create my own printf.

But for some format specifier I had to create, I need a convert function.

I found this code on a specific website, I can give you the link if you want to, but I do not understand why they use a buffer and how does it work.

why ptr could'nt be : *ptr = respresentation[num % base]

#include <stdio.h>
#include <stdarg.h>
    
char* convert(unsigned int num, int base){
   char Representation[] = "0123456789ABCDEF";
   char buffer[50];
   char* ptr = nullptr;

   ptr = &buffer[49];
   *ptr = '\0';

    while(num != 0){
        *--ptr = Representation[num % base];
        num = num / base;
    }

    return(ptr);
};
1

There are 1 best solutions below

0
Jabberwocky On

Your function is wrong because if returns the pointer to a local variable. This may appear to work under certain circumstances, but as explained in numerous comments this yields undefined behaviour because as soon as the function terminates, the local variables do no longer exist.

*--ptr = foo is the same as ptr = ptr - 1; *ptr = foo.

And this is a corrected version of your function and an example of how to call it.

It is rather C code than C++ code (BTW are you actually programming in C or in C++?) and there may be errors as I haven't properly tested it.

#include <stdio.h>
#include <string.h>

#define BUFFER_LENGTH 50      // define length of buffer in one place,
                              // avoids magic numbers all over the place

char* convert(unsigned int num, int base, char *buffer) {
  static char Representation[] = "0123456789ABCDEF";

  char *ptr = &buffer[BUFFER_LENGTH - 1];  // ptr points at the end of the buffer
  *ptr = '\0';                             // put a null terminator for the string

  while (num != 0) {
    *--ptr = Representation[num % base];   
    num = num / base;
  }
                                           // now ptr points to the beginning of the
                                           // string we want

  memmove(buffer, ptr, strlen(ptr) + 1);   // move the string at the beginning
                                           // of the buffer
  return buffer;
};


int main()
{
  char buffer[BUFFER_LENGTH];   // we provide the buffer so it
                                // still exists once convert has terminated
  puts(convert(0xF1234ABC, 16, buffer));
}

For memmove read it's documentation.

BTW: 50 is too much for BUFFER_LENGTH. As an exercise I le you find out yourself which is the maximum buffer size actually needed.