2

I need to convert an unsigned 64-bit integer into a string. That is in Base 36, or characters 0-Z. ulltoa does not exist in the Linux manpages. But sprintf DOES. How do I use sprintf to achieve the desired result? i.e. what formatting % stuff?

Or if snprintf does not work, then how do I do this?

unixman83
  • 9,421
  • 10
  • 68
  • 102

1 Answers1

4

You can always just write your own conversion function. The following idea is stolen from heavily inspired by this fine answer:

char * int2base36(unsigned int n, char * buf, size_t buflen)
{
  static const char digits[] = "0123456789ABCDEFGHI...";

  if (buflen < 1) return NULL; // buffer too small!

  char * b = buf + buflen;
  *--b = 0;

  do {
    if (b == buf) return NULL; // buffer too small!

    *--b = digits[n % 36];
    n /= 36;
  } while(n);

  return b;
}

This will return a pointer to a null-terminated string containing the base36-representation of n, placed in a buffer that you provide. Usage:

char buf[100];
std::cout << int2base36(37, buf, 100);

If you want and you're single-threaded, you can also make the char buffer static -- I guess you can figure out a suitable maximal length:

char * int2base36_not_threadsafe(unsigned int n)
{
  static char buf[128];
  static const size_t buflen = 128;

  // rest as above
Community
  • 1
  • 1
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    This assumes the buffer is full of `NULL`s at the beginning. If you have a buffer of size 32 and you use this function and print the buffer and the buffer wasn't full of nulls, it'll print up to the size of the buffer (but not more) number oferroneous characters. – Seth Carnegie Aug 28 '11 at 01:43
  • 1
    Also this function accepts `unsigned int` which isn't (I assume) 64 bits on a 32 bit system. Should be `unsigned long long` right? – Seth Carnegie Aug 28 '11 at 01:46
  • @Pete: To be fair, I'm pretty much outright stealing this idea from [this answer](http://stackoverflow.com/questions/6920554/source-code-in-embedded-c-for-unsigned-integer-to-string/6920840#6920840) following a lot of flak I got for proposing a `malloc()`-based solution. Their approach requires you to actually pass the end of the string, while I chose to go for beginning plus length here, in the thread-safe version. The unsafe version is even easier to use of course. I'll added the credits! – Kerrek SB Aug 28 '11 at 01:52
  • @Seth: I don't understand your objection. I return a pointer to a well-defined string, properly null-terminated. Yes, the integral type doesn't have a specific width in my example, but I trust the OP to be able to modify this to taste. – Kerrek SB Aug 28 '11 at 02:00
  • @Kerrek your updated answer doesn't have the problem it had before. – Seth Carnegie Aug 28 '11 at 02:03