Source code in embedded C for unsigned integer to string

14,728

Solution 1

Try this:

char *dec(unsigned x, char *s)
{
    *--s = 0;
    if (!x) *--s = '0';
    for (; x; x/=10) *--s = '0'+x%10;
    return s;
}

You call it with a pointer to the end of a caller-provided buffer, and the function returns the pointer to the beginning of the string. The buffer should have length at least 3*sizeof(int)+1 to be safe.

Of course this is easily adapted to other bases.

Solution 2

Theres a lot of itoa source files easily found on google... That should give you what you want, eg. itoa from opensource.apple.com

Or write it from scratch, it's not too hard.

Solution 3

#include <stdint.h>
#include <string.h>

char * utox(uint32_t n) {
    static char hexstr[sizeof(n)*2+1];
    char * p = hexstr + sizeof(hexstr) -1;
    int x;

    memset(hexstr, '0', sizeof(hexstr));

    *p-- = '\0';

    while (n) {
        x = n % 16;
        if (x < 10)
            *p-- = '0' + x;
        else
            *p-- = 'A' + x - 10;

        n /= 16;
    }

    return hexstr;
}

This should do it, it zero pads. Simply changing the type of n in the function parameters will make it work for any integer type/size.

Solution 4

That's not terribly hard. Keep dividing by 10 and use the remainder mod 10 as an index into "0123455679". You build this up from right to left, so you have to buffer the result and return it in reverse:

char * utoa(unsigned int n)
{
  char * res, buf[30]; // long enough for largest number
  unsigned int i, counter = 0;

  if (n == 0)
    buf[counter++] = '0';

  for ( ; n; n /= 10)
    buf[counter++] = "0123456789"[n%10];

  res = malloc(counter);

  for (i = 0; i < counter; ++i)
    res[i] = buf[counter - i - 1];

  return res;
}

Solution 5

Most of the functions mentioned/suggested here uses modulus % operator, which is very expensive for embedded system.

So using divide by 10 idea is the only prominent option I guess. Here it is:

/*for byte which is 3 digit most*/


void itoa(unsigned char value,char *desitination)
{
desitination[0] = '\0';
desitination[1] = '\0';
desitination[2] = '\0';
desitination[3] = '\0';//you at least 4 char array, last char is NULL
while (value >= 100)
{
    desitination[0]++;
    value -= 100;
}
desitination[1] = '0';

while (value >= 10)
{
     desitination[1]++;
     value -= 10;
}
value+= '0';
desitination[2] =value;
}
Share:
14,728
riscy
Author by

riscy

Professional embedded system engineer including window application mostly in C# and IronPython. Also experts in electronics including linear, psu, sensor, etc.

Updated on June 06, 2022

Comments

  • riscy
    riscy almost 2 years

    Without resorting to standard library utoa, I'm looking for source code of utoa so I may customise it for specific project. I have unsigned integer (32 bits) with output such as 0xFFFF_FFFF

    I also looking for source code for unsigned integer and half word to string in binary format.

  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE almost 13 years
    I'm struggling to resist giving -1 to a useless-use-of-malloc as an answer to an embedded systems question...
  • Kerrek SB
    Kerrek SB almost 13 years
    Well, you have to put the result somewhere. I trust the OP is flexible enough to adapt this to her needs, as this detail has clearly nothing to do with the basic algorithm!
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE almost 13 years
    That's why I didn't -1 it. But really, those of us who know better should be setting a good example, rather than leaving it to the OP to fix the solution (and I'd guess a good half of question-askers would "fix" your answer to use a static buffer rather than a caller-provided buffer, which is not a good thing...)
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE almost 13 years
    By the way, indexing into "0123456789" is just a really inefficient way to write '0'+n, and the latter is not a hack, it's required to work as part of the language.
  • Kerrek SB
    Kerrek SB almost 13 years
    The former allows for arbitrary symbols, though :-) But use whatever floats your boat. (About "really inefficient": My method causes one additional assembly instruction over '0'+n%10...)
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE almost 13 years
    And 11 bytes of constant string data. :-) In PIC libraries, it can also introduce a GOT-register dependency (for relative addressing) into a function that otherwise would have been purely position-independent even without -fPIC.
  • riscy
    riscy almost 13 years
    Thank, I give it a go for base 16 (hex).
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE almost 13 years
    For base 16 you'll need to either special-case digits <10 and >=10 separately or use Kerrek's string indexing solution.
  • EboMike
    EboMike almost 13 years
    Obviously, this solution is not thread-safe. (Not that the OP cited that as a requirement.)
  • Vinicius Kamakura
    Vinicius Kamakura almost 13 years
    It is an embedded system, usually this is fine unless he wants to use that in a ISR or with a threaded RTOS. I like this solution most of the time because I can be sure of the array bounds so its safer. It is trivial to instead of manage the array myself, operate on a pointer.
  • EboMike
    EboMike almost 13 years
    My preferred solution is to have the caller pass a buffer (and buffer size) in. But hey, many roads lead to Rome...
  • Nedo
    Nedo about 4 years
    Very clever! I have a question though: why do you decrease the pointer to assign the null terminator at the beginning of the function? It seems to me that you are loosing one byte of the buffer that way. Why not *s = 0?
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE about 4 years
    @Nedo: By "end" I meant one past the last index, i.e. buf + sizeof buf. IMO this is the standard idiom foror "end" in C; the other version has off-by-one quirks comparable to one-based indexing.