Source code in embedded C for unsigned integer to string
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;
}
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, 2022Comments
-
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 almost 13 yearsI'm struggling to resist giving -1 to a useless-use-of-
malloc
as an answer to an embedded systems question... -
Kerrek SB almost 13 yearsWell, 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 almost 13 yearsThat'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 almost 13 yearsBy 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 almost 13 yearsThe 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 almost 13 yearsAnd 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 almost 13 yearsThank, I give it a go for base 16 (hex).
-
R.. GitHub STOP HELPING ICE almost 13 yearsFor base 16 you'll need to either special-case digits <10 and >=10 separately or use Kerrek's string indexing solution.
-
EboMike almost 13 yearsObviously, this solution is not thread-safe. (Not that the OP cited that as a requirement.)
-
Vinicius Kamakura almost 13 yearsIt 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 almost 13 yearsMy preferred solution is to have the caller pass a buffer (and buffer size) in. But hey, many roads lead to Rome...
-
Nedo about 4 yearsVery 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 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.