Convert long to char array without using library functions - c

How can I convert a long variable to a char[] variable without using library functions?

Working example (1) - thread-safe, requires min. buffsize = 40.
static const char *
xllitoa(long long int x, char *buff)
{
char *p = buff + 40;
int sign = 0;
*(p--) = 0;
if (x < 0) sign = 1;
else x = -x;
do { *(p--) = -(x % 10) + '0'; x /= 10; } while(x);
if (sign) *(p--) = '-';
return (const char *)(p+1);
}
Working example (2) - not thread-safe
static const char *
xllitoa(long long int x)
{
static char buff[40];
char *p = buff + 40;
int sign = 0;
*(p--) = 0;
if (x < 0) sign = 1;
else x = -x;
do { *(p--) = -(x % 10) + '0'; x /= 10; } while(x);
if (sign) *(p--) = '-';
return (const char *)(p+1);
}
Many thanks to reviewers. Now it accepts LLONG_MAX and LLONG_MIN as well.

After accept answer that works for all values LONG_MIN to LONG_MAX.
This uses a helper function to recursive work with negative values of n. By using negative values, there is no problem with LONG_MIN.
static char *ltostr_helper(long n, char *dest) {
if (n <= -10)
dest = ltostr_helper(n / 10, dest);
*dest++ = (char) ('0' - n % 10);
return dest; // return pointer to end
}
void ltostr(long n, char *dest) {
if (n < 0) {
*dest++ = '-';
} else {
n = -n;
}
*ltostr_helper(n, dest) = '\0';
}
int main(void) {
char buf[sizeof(long) * CHAR_BIT /3 + 3];// size buffer to our needs
ltostr(0, buf); printf("%s\n", buf);
ltostr(123, buf); printf("%s\n", buf);
ltostr(-123, buf); printf("%s\n", buf);
ltostr(LONG_MAX, buf); printf("%s\n", buf);
ltostr(LONG_MIN, buf); printf("%s\n", buf);
return 0;
}
Output
0
123
-123
9223372036854775807
-9223372036854775808

Related

Decimal to octal converter in c [duplicate]

I can use the strtol function for turning a base36 based value (saved as a string) into a long int:
long int val = strtol("ABCZX123", 0, 36);
Is there a standard function that allows the inversion of this? That is, to convert a long int val variable into a base36 string, to obtain "ABCZX123" again?
There's no standard function for this. You'll need to write your own one.
Usage example: https://godbolt.org/z/MhRcNA
const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char *reverse(char *str)
{
char *end = str;
char *start = str;
if(!str || !*str) return str;
while(*(end + 1)) end++;
while(end > start)
{
int ch = *end;
*end-- = *start;
*start++ = ch;
}
return str;
}
char *tostring(char *buff, long long num, int base)
{
int sign = num < 0;
char *savedbuff = buff;
if(base < 2 || base >= sizeof(digits)) return NULL;
if(buff)
{
do
{
*buff++ = digits[abs(num % base)];
num /= base;
}while(num);
if(sign)
{
*buff++ = '-';
}
*buff = 0;
reverse(savedbuff);
}
return savedbuff;
}
One of the missing attributes of this "Convert long integer to base 36 string" is string management.
The below suffers from a potential buffer overflow when destination is too small.
char *long_to_string(char *destination, long num, int base);
(Assuming 32-bit long) Consider the overflow of below as the resultant string should be "-10000000000000000000000000000000", which needs 34 bytes to encode the string.
char buffer[33]; // Too small
long_to_string(buffer, LONG_MIN, 2); // Oops!
An alternative would pass in the buffer size and then provide some sort of error signaling when the buffer is too small.
char* longtostr(char *dest, size_t size, long a, int base)
Since C99, code instead could use a compound literal to provide the needed space - without calling code trying to compute the needed size nor explicitly allocate the buffer.
The returned string pointer from TO_BASE(long x, int base) is valid until the end of the block.
#include <assert.h>
#include <limits.h>
#define TO_BASE_N (sizeof(long)*CHAR_BIT + 2)
// v. compound literal .v
#define TO_BASE(x, b) my_to_base((char [TO_BASE_N]){""}, (x), (b))
char *my_to_base(char *buf, long a, int base) {
assert(base >= 2 && base <= 36);
long i = a < 0 ? a : -a; // use the negative side - this handle _MIN, _MAX nicely
char *s = &buf[TO_BASE_N - 1];
*s = '\0';
do {
s--;
*s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-(i % base)];
i /= base;
} while (i);
if (a < 0) {
s--;
*s = '-';
}
// Could add memmove here to move the used buffer to the beginning
return s;
}
#include <limits.h>
#include <stdio.h>
int main(void) {
long ip1 = 0x01020304;
long ip2 = 0x05060708;
long ip3 = LONG_MIN;
printf("%s %s\n", TO_BASE(ip1, 16), TO_BASE(ip2, 16), TO_BASE(ip3, 16));
printf("%s %s\n", TO_BASE(ip1, 2), TO_BASE(ip2, 2), TO_BASE(ip3, 2));
puts(TO_BASE(ip1, 8));
puts(TO_BASE(ip1, 36));
puts(TO_BASE(ip3, 10));
}
Here is another option with no need for source array of charaters, but less portable since not all character encodings have contiguous alphabetic characters, for example EBCDIC. Test HERE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
char get_chars(long long value)
{
if (value >= 0 && value <= 9)
return value + '0';
else
return value - 10 + 'A';
}
void reverse_string(char *str)
{
int len = strlen(str);
for (int i = 0; i < len/2; i++)
{
char temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
}
char* convert_to_base(char *res, int base, long long input)
{
bool flag = 0;
int index = 0;
if(input < 0){
input = llabs(input);
flag = 1;
}
else if(input == 0){
res[index++] = '0';
res[index] = '\0';
return res;
}
while(input > 0)
{
res[index++] = get_chars(input % base);
input /= base;
}
if(flag){
res[index++] = '-';
}
res[index] = '\0';
reverse_string(res);
return res;
}
int main() {
long long input = 0;
printf("** Integer to Base-36 **\n ");
printf("Enter a valid number: ");
scanf("%lld", &input);
if(input >= LLONG_MAX && input <= LLONG_MIN){
printf("Invalid number");
return 0;
}
int base = 36;
char res[100];
printf("%lld -> %s\n", input, convert_to_base(res, base, input));
return 0;
}

Convert long integer(decimal) to base 36 string (strtol inverted function in C)

I can use the strtol function for turning a base36 based value (saved as a string) into a long int:
long int val = strtol("ABCZX123", 0, 36);
Is there a standard function that allows the inversion of this? That is, to convert a long int val variable into a base36 string, to obtain "ABCZX123" again?
There's no standard function for this. You'll need to write your own one.
Usage example: https://godbolt.org/z/MhRcNA
const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char *reverse(char *str)
{
char *end = str;
char *start = str;
if(!str || !*str) return str;
while(*(end + 1)) end++;
while(end > start)
{
int ch = *end;
*end-- = *start;
*start++ = ch;
}
return str;
}
char *tostring(char *buff, long long num, int base)
{
int sign = num < 0;
char *savedbuff = buff;
if(base < 2 || base >= sizeof(digits)) return NULL;
if(buff)
{
do
{
*buff++ = digits[abs(num % base)];
num /= base;
}while(num);
if(sign)
{
*buff++ = '-';
}
*buff = 0;
reverse(savedbuff);
}
return savedbuff;
}
One of the missing attributes of this "Convert long integer to base 36 string" is string management.
The below suffers from a potential buffer overflow when destination is too small.
char *long_to_string(char *destination, long num, int base);
(Assuming 32-bit long) Consider the overflow of below as the resultant string should be "-10000000000000000000000000000000", which needs 34 bytes to encode the string.
char buffer[33]; // Too small
long_to_string(buffer, LONG_MIN, 2); // Oops!
An alternative would pass in the buffer size and then provide some sort of error signaling when the buffer is too small.
char* longtostr(char *dest, size_t size, long a, int base)
Since C99, code instead could use a compound literal to provide the needed space - without calling code trying to compute the needed size nor explicitly allocate the buffer.
The returned string pointer from TO_BASE(long x, int base) is valid until the end of the block.
#include <assert.h>
#include <limits.h>
#define TO_BASE_N (sizeof(long)*CHAR_BIT + 2)
// v. compound literal .v
#define TO_BASE(x, b) my_to_base((char [TO_BASE_N]){""}, (x), (b))
char *my_to_base(char *buf, long a, int base) {
assert(base >= 2 && base <= 36);
long i = a < 0 ? a : -a; // use the negative side - this handle _MIN, _MAX nicely
char *s = &buf[TO_BASE_N - 1];
*s = '\0';
do {
s--;
*s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-(i % base)];
i /= base;
} while (i);
if (a < 0) {
s--;
*s = '-';
}
// Could add memmove here to move the used buffer to the beginning
return s;
}
#include <limits.h>
#include <stdio.h>
int main(void) {
long ip1 = 0x01020304;
long ip2 = 0x05060708;
long ip3 = LONG_MIN;
printf("%s %s\n", TO_BASE(ip1, 16), TO_BASE(ip2, 16), TO_BASE(ip3, 16));
printf("%s %s\n", TO_BASE(ip1, 2), TO_BASE(ip2, 2), TO_BASE(ip3, 2));
puts(TO_BASE(ip1, 8));
puts(TO_BASE(ip1, 36));
puts(TO_BASE(ip3, 10));
}
Here is another option with no need for source array of charaters, but less portable since not all character encodings have contiguous alphabetic characters, for example EBCDIC. Test HERE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
char get_chars(long long value)
{
if (value >= 0 && value <= 9)
return value + '0';
else
return value - 10 + 'A';
}
void reverse_string(char *str)
{
int len = strlen(str);
for (int i = 0; i < len/2; i++)
{
char temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
}
char* convert_to_base(char *res, int base, long long input)
{
bool flag = 0;
int index = 0;
if(input < 0){
input = llabs(input);
flag = 1;
}
else if(input == 0){
res[index++] = '0';
res[index] = '\0';
return res;
}
while(input > 0)
{
res[index++] = get_chars(input % base);
input /= base;
}
if(flag){
res[index++] = '-';
}
res[index] = '\0';
reverse_string(res);
return res;
}
int main() {
long long input = 0;
printf("** Integer to Base-36 **\n ");
printf("Enter a valid number: ");
scanf("%lld", &input);
if(input >= LLONG_MAX && input <= LLONG_MIN){
printf("Invalid number");
return 0;
}
int base = 36;
char res[100];
printf("%lld -> %s\n", input, convert_to_base(res, base, input));
return 0;
}

C int to char array [duplicate]

How do you convert an int (integer) to a string?
I'm trying to make a function that converts the data of a struct into a string to save it in a file.
You can use sprintf to do it, or maybe snprintf if you have it:
char str[ENOUGH];
sprintf(str, "%d", 42);
Where the number of characters (plus terminating char) in the str can be calculated using:
(int)((ceil(log10(num))+1)*sizeof(char))
As pointed out in a comment, itoa() is not a standard, so better use the sprintf() approach suggested in the rival answer!
You can use the itoa() function to convert your integer value to a string.
Here is an example:
int num = 321;
char snum[5];
// Convert 123 to string [buf]
itoa(num, snum, 10);
// Print our string
printf("%s\n", snum);
If you want to output your structure into a file there isn't any need to convert any value beforehand. You can just use the printf format specification to indicate how to output your values and use any of the operators from printf family to output your data.
The short answer is:
snprintf( str, size, "%d", x );
The longer is: first you need to find out sufficient size. snprintf tells you length if you call it with NULL, 0 as first parameters:
snprintf( NULL, 0, "%d", x );
Allocate one character more for null-terminator.
#include <stdio.h>
#include <stdlib.h>
int x = -42;
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
If works for every format string, so you can convert float or double to string by using "%g", you can convert int to hex using "%x", and so on.
After having looked at various versions of itoa for gcc, the most flexible version I have found that is capable of handling conversions to binary, decimal and hexadecimal, both positive and negative is the fourth version found at http://www.strudel.org.uk/itoa/. While sprintf/snprintf have advantages, they will not handle negative numbers for anything other than decimal conversion. Since the link above is either off-line or no longer active, I've included their 4th version below:
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
Here's another way.
#include <stdio.h>
#define atoa(x) #x
int main(int argc, char *argv[])
{
char *string = atoa(1234567890);
printf("%s\n", string);
return 0;
}
Converting anything to a string should either 1) allocate the resultant string or 2) pass in a char * destination and size. Sample code below:
Both work for all int including INT_MIN. They provide a consistent output unlike snprintf() which depends on the current locale.
Method 1: Returns NULL on out-of-memory.
#define INT_DECIMAL_STRING_SIZE(int_type) ((CHAR_BIT*sizeof(int_type)-1)*10/33+3)
char *int_to_string_alloc(int x) {
int i = x;
char buf[INT_DECIMAL_STRING_SIZE(int)];
char *p = &buf[sizeof buf] - 1;
*p = '\0';
if (i >= 0) {
i = -i;
}
do {
p--;
*p = (char) ('0' - i % 10);
i /= 10;
} while (i);
if (x < 0) {
p--;
*p = '-';
}
size_t len = (size_t) (&buf[sizeof buf] - p);
char *s = malloc(len);
if (s) {
memcpy(s, p, len);
}
return s;
}
Method 2: It returns NULL if the buffer was too small.
static char *int_to_string_helper(char *dest, size_t n, int x) {
if (n == 0) {
return NULL;
}
if (x <= -10) {
dest = int_to_string_helper(dest, n - 1, x / 10);
if (dest == NULL) return NULL;
}
*dest = (char) ('0' - x % 10);
return dest + 1;
}
char *int_to_string(char *dest, size_t n, int x) {
char *p = dest;
if (n == 0) {
return NULL;
}
n--;
if (x < 0) {
if (n == 0) return NULL;
n--;
*p++ = '-';
} else {
x = -x;
}
p = int_to_string_helper(p, n, x);
if (p == NULL) return NULL;
*p = 0;
return dest;
}
[Edit] as request by #Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3 is at least the maximum number of char needed to encode the some signed integer type as a string consisting of an optional negative sign, digits, and a null character..
The number of non-sign bits in a signed integer is no more than CHAR_BIT*sizeof(int_type)-1. A base-10 representation of a n-bit binary number takes up to n*log10(2) + 1 digits. 10/33 is slightly more than log10(2). +1 for the sign char and +1 for the null character. Other fractions could be used like 28/93.
Method 3: If one wants to live on the edge and buffer overflow is not a concern, a simple C99 or later solution follows which handles all int.
#include <limits.h>
#include <stdio.h>
static char *itoa_simple_helper(char *dest, int i) {
if (i <= -10) {
dest = itoa_simple_helper(dest, i/10);
}
*dest++ = '0' - i%10;
return dest;
}
char *itoa_simple(char *dest, int i) {
char *s = dest;
if (i < 0) {
*s++ = '-';
} else {
i = -i;
}
*itoa_simple_helper(s, i) = '\0';
return dest;
}
int main() {
char s[100];
puts(itoa_simple(s, 0));
puts(itoa_simple(s, 1));
puts(itoa_simple(s, -1));
puts(itoa_simple(s, 12345));
puts(itoa_simple(s, INT_MAX-1));
puts(itoa_simple(s, INT_MAX));
puts(itoa_simple(s, INT_MIN+1));
puts(itoa_simple(s, INT_MIN));
}
Sample output
0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
If you are using GCC, you can use the GNU extension asprintf function.
char* str;
asprintf(&str, "%i", 12313);
free(str);
sprintf is returning the bytes and adds a null byte as well:
# include <stdio.h>
# include <string.h>
int main() {
char buf[1024];
int n = sprintf( buf, "%d", 2415);
printf("%s %d\n", buf, n);
}
Output:
2415 4
/* Function return size of string and convert signed *
* integer to ascii value and store them in array of *
* character with NULL at the end of the array */
int itoa(int value, char *ptr)
{
int count = 0, temp;
if(ptr == NULL)
return 0;
if(value == 0)
{
*ptr = '0';
return 1;
}
if(value < 0)
{
value* = (-1);
*ptr++ = '-';
count++;
}
for(temp=value; temp>0; temp/=10, ptr++);
*ptr = '\0';
for(temp=value; temp>0; temp/=10)
{
*--ptr = temp%10 + '0';
count++;
}
return count;
}
Use function itoa() to convert an integer to a string
For example:
char msg[30];
int num = 10;
itoa(num,msg,10);

Bus error when printing to output file [duplicate]

itoa() is a really handy function to convert a number to a string. Linux does not seem to have itoa(), is there an equivalent function or do I have to use sprintf(str, "%d", num)?
EDIT: Sorry, I should have remembered that this machine is decidedly non-standard, having plugged in various non-standard libc implementations for academic purposes ;-)
As itoa() is indeed non-standard, as mentioned by several helpful commenters, it is best to use sprintf(target_string,"%d",source_int) or (better yet, because it's safe from buffer overflows) snprintf(target_string, size_of_target_string_in_bytes, "%d", source_int). I know it's not quite as concise or cool as itoa(), but at least you can Write Once, Run Everywhere (tm) ;-)
Here's the old (edited) answer
You are correct in stating that the default gcc libc does not include itoa(), like several other platforms, due to it not technically being a part of the standard. See here for a little more info. Note that you have to
#include <stdlib.h>
Of course you already know this, because you wanted to use itoa() on Linux after presumably using it on another platform, but... the code (stolen from the link above) would look like:
Example
/* itoa example */
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i;
char buffer [33];
printf ("Enter a number: ");
scanf ("%d",&i);
itoa (i,buffer,10);
printf ("decimal: %s\n",buffer);
itoa (i,buffer,16);
printf ("hexadecimal: %s\n",buffer);
itoa (i,buffer,2);
printf ("binary: %s\n",buffer);
return 0;
}
Output:
Enter a number: 1750
decimal: 1750
hexadecimal: 6d6
binary: 11011010110
itoa is not a standard C function. You can implement your own. It appeared in the first edition of Kernighan and Ritchie's The C Programming Language, on page 60. The second edition of The C Programming Language ("K&R2") contains the following implementation of itoa, on page 64. The book notes several issues with this implementation, including the fact that it does not correctly handle the most negative number
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
The function reverse used above is implemented two pages earlier:
#include <string.h>
/* reverse: reverse string s in place */
void reverse(char s[])
{
int i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
If you are calling it a lot, the advice of "just use snprintf" can be annoying. So here's what you probably want:
const char *my_itoa_buf(char *buf, size_t len, int num)
{
static char loc_buf[sizeof(int) * CHAR_BITS]; /* not thread safe */
if (!buf)
{
buf = loc_buf;
len = sizeof(loc_buf);
}
if (snprintf(buf, len, "%d", num) == -1)
return ""; /* or whatever */
return buf;
}
const char *my_itoa(int num)
{ return my_itoa_buf(NULL, 0, num); }
Edit: I just found out about std::to_string which is identical in operation to my own function below. It was introduced in C++11 and is available in recent versions of gcc, at least as early as 4.5 if you enable the c++0x extensions.
Not only is itoa missing from gcc, it's not the handiest function to use since you need to feed it a buffer. I needed something that could be used in an expression so I came up with this:
std::string itos(int n)
{
const int max_size = std::numeric_limits<int>::digits10 + 1 /*sign*/ + 1 /*0-terminator*/;
char buffer[max_size] = {0};
sprintf(buffer, "%d", n);
return std::string(buffer);
}
Ordinarily it would be safer to use snprintf instead of sprintf but the buffer is carefully sized to be immune to overrun.
See an example: http://ideone.com/mKmZVE
As Matt J wrote, there is itoa, but it's not standard. Your code will be more portable if you use snprintf.
Following function allocates just enough memory to keep string representation of the given number and then writes the string representation into this area using standard sprintf method.
char *itoa(long n)
{
int len = n==0 ? 1 : floor(log10l(labs(n)))+1;
if (n<0) len++; // room for negative sign '-'
char *buf = calloc(sizeof(char), len+1); // +1 for null
snprintf(buf, len+1, "%ld", n);
return buf;
}
Don't forget to free up allocated memory when out of need:
char *num_str = itoa(123456789L);
// ...
free(num_str);
N.B. As snprintf copies n-1 bytes, we have to call snprintf(buf, len+1, "%ld", n) (not just snprintf(buf, len, "%ld", n))
Where is the itoa function in Linux?
There is no such function in Linux. I use this code instead.
/*
=============
itoa
Convert integer to string
PARAMS:
- value A 64-bit number to convert
- str Destination buffer; should be 66 characters long for radix2, 24 - radix8, 22 - radix10, 18 - radix16.
- radix Radix must be in range -36 .. 36. Negative values used for signed numbers.
=============
*/
char* itoa (unsigned long long value, char str[], int radix)
{
char buf [66];
char* dest = buf + sizeof(buf);
boolean sign = false;
if (value == 0) {
memcpy (str, "0", 2);
return str;
}
if (radix < 0) {
radix = -radix;
if ( (long long) value < 0) {
value = -value;
sign = true;
}
}
*--dest = '\0';
switch (radix)
{
case 16:
while (value) {
* --dest = '0' + (value & 0xF);
if (*dest > '9') *dest += 'A' - '9' - 1;
value >>= 4;
}
break;
case 10:
while (value) {
*--dest = '0' + (value % 10);
value /= 10;
}
break;
case 8:
while (value) {
*--dest = '0' + (value & 7);
value >>= 3;
}
break;
case 2:
while (value) {
*--dest = '0' + (value & 1);
value >>= 1;
}
break;
default: // The slow version, but universal
while (value) {
*--dest = '0' + (value % radix);
if (*dest > '9') *dest += 'A' - '9' - 1;
value /= radix;
}
break;
}
if (sign) *--dest = '-';
memcpy (str, dest, buf +sizeof(buf) - dest);
return str;
}
Reading the code of guys who do it for a living will get you a LONG WAY.
Check out how guys from MySQL did it. The source is VERY WELL COMMENTED and will teach you much more than hacked up solutions found all over the place.
MySQL's implementation of int2str
I provide the mentioned implementation here; the link is here for reference and should be used to read the full implementation.
char *
int2str(long int val, char *dst, int radix,
int upcase)
{
char buffer[65];
char *p;
long int new_val;
char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
ulong uval= (ulong) val;
if (radix < 0)
{
if (radix < -36 || radix > -2)
return NullS;
if (val < 0)
{
*dst++ = '-';
/* Avoid integer overflow in (-val) for LLONG_MIN (BUG#31799). */
uval = (ulong)0 - uval;
}
radix = -radix;
}
else if (radix > 36 || radix < 2)
return NullS;
/*
The slightly contorted code which follows is due to the fact that
few machines directly support unsigned long / and %. Certainly
the VAX C compiler generates a subroutine call. In the interests
of efficiency (hollow laugh) I let this happen for the first digit
only; after that "val" will be in range so that signed integer
division will do. Sorry 'bout that. CHECK THE CODE PRODUCED BY
YOUR C COMPILER. The first % and / should be unsigned, the second
% and / signed, but C compilers tend to be extraordinarily
sensitive to minor details of style. This works on a VAX, that's
all I claim for it.
*/
p = &buffer[sizeof(buffer)-1];
*p = '\0';
new_val= uval / (ulong) radix;
*--p = dig_vec[(uchar) (uval- (ulong) new_val*(ulong) radix)];
val = new_val;
while (val != 0)
{
ldiv_t res;
res=ldiv(val,radix);
*--p = dig_vec[res.rem];
val= res.quot;
}
while ((*dst++ = *p++) != 0) ;
return dst-1;
}
i tried my own implementation of itoa(), it seem's work in binary, octal, decimal and hex
#define INT_LEN (10)
#define HEX_LEN (8)
#define BIN_LEN (32)
#define OCT_LEN (11)
static char * my_itoa ( int value, char * str, int base )
{
int i,n =2,tmp;
char buf[BIN_LEN+1];
switch(base)
{
case 16:
for(i = 0;i<HEX_LEN;++i)
{
if(value/base>0)
{
n++;
}
}
snprintf(str, n, "%x" ,value);
break;
case 10:
for(i = 0;i<INT_LEN;++i)
{
if(value/base>0)
{
n++;
}
}
snprintf(str, n, "%d" ,value);
break;
case 8:
for(i = 0;i<OCT_LEN;++i)
{
if(value/base>0)
{
n++;
}
}
snprintf(str, n, "%o" ,value);
break;
case 2:
for(i = 0,tmp = value;i<BIN_LEN;++i)
{
if(tmp/base>0)
{
n++;
}
tmp/=base;
}
for(i = 1 ,tmp = value; i<n;++i)
{
if(tmp%2 != 0)
{
buf[n-i-1] ='1';
}
else
{
buf[n-i-1] ='0';
}
tmp/=base;
}
buf[n-1] = '\0';
strcpy(str,buf);
break;
default:
return NULL;
}
return str;
}
direct copy to buffer : 64 bit integer itoa hex :
char* itoah(long num, char* s, int len)
{
long n, m = 16;
int i = 16+2;
int shift = 'a'- ('9'+1);
if(!s || len < 1)
return 0;
n = num < 0 ? -1 : 1;
n = n * num;
len = len > i ? i : len;
i = len < i ? len : i;
s[i-1] = 0;
i--;
if(!num)
{
if(len < 2)
return &s[i];
s[i-1]='0';
return &s[i-1];
}
while(i && n)
{
s[i-1] = n % m + '0';
if (s[i-1] > '9')
s[i-1] += shift ;
n = n/m;
i--;
}
if(num < 0)
{
if(i)
{
s[i-1] = '-';
i--;
}
}
return &s[i];
}
note: change long to long long for 32 bit machine. long to int in case for 32 bit integer. m is the radix. When decreasing radix, increase number of characters (variable i). When increasing radix, decrease number of characters (better). In case of unsigned data type, i just becomes 16 + 1.
Here is a much improved version of Archana's solution. It works for any radix 1-16, and numbers <= 0, and it shouldn't clobber memory.
static char _numberSystem[] = "0123456789ABCDEF";
static char _twosComp[] = "FEDCBA9876543210";
static void safestrrev(char *buffer, const int bufferSize, const int strlen)
{
int len = strlen;
if (len > bufferSize)
{
len = bufferSize;
}
for (int index = 0; index < (len / 2); index++)
{
char ch = buffer[index];
buffer[index] = buffer[len - index - 1];
buffer[len - index - 1] = ch;
}
}
static int negateBuffer(char *buffer, const int bufferSize, const int strlen, const int radix)
{
int len = strlen;
if (len > bufferSize)
{
len = bufferSize;
}
if (radix == 10)
{
if (len < (bufferSize - 1))
{
buffer[len++] = '-';
buffer[len] = '\0';
}
}
else
{
int twosCompIndex = 0;
for (int index = 0; index < len; index++)
{
if ((buffer[index] >= '0') && (buffer[index] <= '9'))
{
twosCompIndex = buffer[index] - '0';
}
else if ((buffer[index] >= 'A') && (buffer[index] <= 'F'))
{
twosCompIndex = buffer[index] - 'A' + 10;
}
else if ((buffer[index] >= 'a') && (buffer[index] <= 'f'))
{
twosCompIndex = buffer[index] - 'a' + 10;
}
twosCompIndex += (16 - radix);
buffer[index] = _twosComp[twosCompIndex];
}
if (len < (bufferSize - 1))
{
buffer[len++] = _numberSystem[radix - 1];
buffer[len] = 0;
}
}
return len;
}
static int twosNegation(const int x, const int radix)
{
int n = x;
if (x < 0)
{
if (radix == 10)
{
n = -x;
}
else
{
n = ~x;
}
}
return n;
}
static char *safeitoa(const int x, char *buffer, const int bufferSize, const int radix)
{
int strlen = 0;
int n = twosNegation(x, radix);
int nuberSystemIndex = 0;
if (radix <= 16)
{
do
{
if (strlen < (bufferSize - 1))
{
nuberSystemIndex = (n % radix);
buffer[strlen++] = _numberSystem[nuberSystemIndex];
buffer[strlen] = '\0';
n = n / radix;
}
else
{
break;
}
} while (n != 0);
if (x < 0)
{
strlen = negateBuffer(buffer, bufferSize, strlen, radix);
}
safestrrev(buffer, bufferSize, strlen);
return buffer;
}
return NULL;
}
Where is the itoa function in Linux?
As itoa() is not standard in C, various versions with various function signatures exists.
char *itoa(int value, char *str, int base); is common in *nix.
Should it be missing from Linux or if code does not want to limit portability, code could make it own.
Below is a version that does not have trouble with INT_MIN and handles problem buffers: NULL or an insufficient buffer returns NULL.
#include <stdlib.h>
#include <limits.h>
#include <string.h>
// Buffer sized for a decimal string of a `signed int`, 28/93 > log10(2)
#define SIGNED_PRINT_SIZE(object) ((sizeof(object) * CHAR_BIT - 1)* 28 / 93 + 3)
char *itoa_x(int number, char *dest, size_t dest_size) {
if (dest == NULL) {
return NULL;
}
char buf[SIGNED_PRINT_SIZE(number)];
char *p = &buf[sizeof buf - 1];
// Work with negative absolute value
int neg_num = number < 0 ? number : -number;
// Form string
*p = '\0';
do {
*--p = (char) ('0' - neg_num % 10);
neg_num /= 10;
} while (neg_num);
if (number < 0) {
*--p = '-';
}
// Copy string
size_t src_size = (size_t) (&buf[sizeof buf] - p);
if (src_size > dest_size) {
// Not enough room
return NULL;
}
return memcpy(dest, p, src_size);
}
Below is a C99 or later version that handles any base [2...36]
char *itoa_x(int number, char *dest, size_t dest_size, int base) {
if (dest == NULL || base < 2 || base > 36) {
return NULL;
}
char buf[sizeof number * CHAR_BIT + 2]; // worst case: itoa(INT_MIN,,,2)
char *p = &buf[sizeof buf - 1];
// Work with negative absolute value to avoid UB of `abs(INT_MIN)`
int neg_num = number < 0 ? number : -number;
// Form string
*p = '\0';
do {
*--p = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-(neg_num % base)];
neg_num /= base;
} while (neg_num);
if (number < 0) {
*--p = '-';
}
// Copy string
size_t src_size = (size_t) (&buf[sizeof buf] - p);
if (src_size > dest_size) {
// Not enough room
return NULL;
}
return memcpy(dest, p, src_size);
}
For a C89 and onward compliant code, replace inner loop with
div_t qr;
do {
qr = div(neg_num, base);
*--p = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-qr.rem];
neg_num = qr.quot;
} while (neg_num);
glibc internal implementation
glibc 2.28 has an internal implementation:
stdio-common/_itoa.c
sysdeps/generic/_itoa.h
which is used in several places internally, but I could not find if it can be exposed or how.
At least that should be a robust implementation if you are willing to extract it.
This question asks how to roll your own: How to convert an int to string in C?
I would prefer this: https://github.com/wsq003/itoa_for_linux
It should be the fastest itoa() ever. We use itoa() instead of sprintf() for performance reason, so a fastest itoa() with limited feature is reasonable and worthwhile.
If you just want to print them:
void binary(unsigned int n)
{
for(int shift=sizeof(int)*8-1;shift>=0;shift--)
{
if (n >> shift & 1)
printf("1");
else
printf("0");
}
printf("\n");
}
The replacement with snprintf is NOT complete!
It covers only bases: 2, 8, 10, 16, whereas itoa works for bases between 2 and 36.
Since I was searching a replacement for base 32, I guess I'll have to code my own!
I have used _itoa(...) on RedHat 6 and GCC compiler. It works.
You can use this program instead of sprintf.
void itochar(int x, char *buffer, int radix);
int main()
{
char buffer[10];
itochar(725, buffer, 10);
printf ("\n %s \n", buffer);
return 0;
}
void itochar(int x, char *buffer, int radix)
{
int i = 0 , n,s;
n = s;
while (n > 0)
{
s = n%radix;
n = n/radix;
buffer[i++] = '0' + s;
}
buffer[i] = '\0';
strrev(buffer);
}

int to string in C? [duplicate]

itoa() is a really handy function to convert a number to a string. Linux does not seem to have itoa(), is there an equivalent function or do I have to use sprintf(str, "%d", num)?
EDIT: Sorry, I should have remembered that this machine is decidedly non-standard, having plugged in various non-standard libc implementations for academic purposes ;-)
As itoa() is indeed non-standard, as mentioned by several helpful commenters, it is best to use sprintf(target_string,"%d",source_int) or (better yet, because it's safe from buffer overflows) snprintf(target_string, size_of_target_string_in_bytes, "%d", source_int). I know it's not quite as concise or cool as itoa(), but at least you can Write Once, Run Everywhere (tm) ;-)
Here's the old (edited) answer
You are correct in stating that the default gcc libc does not include itoa(), like several other platforms, due to it not technically being a part of the standard. See here for a little more info. Note that you have to
#include <stdlib.h>
Of course you already know this, because you wanted to use itoa() on Linux after presumably using it on another platform, but... the code (stolen from the link above) would look like:
Example
/* itoa example */
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i;
char buffer [33];
printf ("Enter a number: ");
scanf ("%d",&i);
itoa (i,buffer,10);
printf ("decimal: %s\n",buffer);
itoa (i,buffer,16);
printf ("hexadecimal: %s\n",buffer);
itoa (i,buffer,2);
printf ("binary: %s\n",buffer);
return 0;
}
Output:
Enter a number: 1750
decimal: 1750
hexadecimal: 6d6
binary: 11011010110
itoa is not a standard C function. You can implement your own. It appeared in the first edition of Kernighan and Ritchie's The C Programming Language, on page 60. The second edition of The C Programming Language ("K&R2") contains the following implementation of itoa, on page 64. The book notes several issues with this implementation, including the fact that it does not correctly handle the most negative number
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
The function reverse used above is implemented two pages earlier:
#include <string.h>
/* reverse: reverse string s in place */
void reverse(char s[])
{
int i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
If you are calling it a lot, the advice of "just use snprintf" can be annoying. So here's what you probably want:
const char *my_itoa_buf(char *buf, size_t len, int num)
{
static char loc_buf[sizeof(int) * CHAR_BITS]; /* not thread safe */
if (!buf)
{
buf = loc_buf;
len = sizeof(loc_buf);
}
if (snprintf(buf, len, "%d", num) == -1)
return ""; /* or whatever */
return buf;
}
const char *my_itoa(int num)
{ return my_itoa_buf(NULL, 0, num); }
Edit: I just found out about std::to_string which is identical in operation to my own function below. It was introduced in C++11 and is available in recent versions of gcc, at least as early as 4.5 if you enable the c++0x extensions.
Not only is itoa missing from gcc, it's not the handiest function to use since you need to feed it a buffer. I needed something that could be used in an expression so I came up with this:
std::string itos(int n)
{
const int max_size = std::numeric_limits<int>::digits10 + 1 /*sign*/ + 1 /*0-terminator*/;
char buffer[max_size] = {0};
sprintf(buffer, "%d", n);
return std::string(buffer);
}
Ordinarily it would be safer to use snprintf instead of sprintf but the buffer is carefully sized to be immune to overrun.
See an example: http://ideone.com/mKmZVE
As Matt J wrote, there is itoa, but it's not standard. Your code will be more portable if you use snprintf.
Following function allocates just enough memory to keep string representation of the given number and then writes the string representation into this area using standard sprintf method.
char *itoa(long n)
{
int len = n==0 ? 1 : floor(log10l(labs(n)))+1;
if (n<0) len++; // room for negative sign '-'
char *buf = calloc(sizeof(char), len+1); // +1 for null
snprintf(buf, len+1, "%ld", n);
return buf;
}
Don't forget to free up allocated memory when out of need:
char *num_str = itoa(123456789L);
// ...
free(num_str);
N.B. As snprintf copies n-1 bytes, we have to call snprintf(buf, len+1, "%ld", n) (not just snprintf(buf, len, "%ld", n))
Where is the itoa function in Linux?
There is no such function in Linux. I use this code instead.
/*
=============
itoa
Convert integer to string
PARAMS:
- value A 64-bit number to convert
- str Destination buffer; should be 66 characters long for radix2, 24 - radix8, 22 - radix10, 18 - radix16.
- radix Radix must be in range -36 .. 36. Negative values used for signed numbers.
=============
*/
char* itoa (unsigned long long value, char str[], int radix)
{
char buf [66];
char* dest = buf + sizeof(buf);
boolean sign = false;
if (value == 0) {
memcpy (str, "0", 2);
return str;
}
if (radix < 0) {
radix = -radix;
if ( (long long) value < 0) {
value = -value;
sign = true;
}
}
*--dest = '\0';
switch (radix)
{
case 16:
while (value) {
* --dest = '0' + (value & 0xF);
if (*dest > '9') *dest += 'A' - '9' - 1;
value >>= 4;
}
break;
case 10:
while (value) {
*--dest = '0' + (value % 10);
value /= 10;
}
break;
case 8:
while (value) {
*--dest = '0' + (value & 7);
value >>= 3;
}
break;
case 2:
while (value) {
*--dest = '0' + (value & 1);
value >>= 1;
}
break;
default: // The slow version, but universal
while (value) {
*--dest = '0' + (value % radix);
if (*dest > '9') *dest += 'A' - '9' - 1;
value /= radix;
}
break;
}
if (sign) *--dest = '-';
memcpy (str, dest, buf +sizeof(buf) - dest);
return str;
}
Reading the code of guys who do it for a living will get you a LONG WAY.
Check out how guys from MySQL did it. The source is VERY WELL COMMENTED and will teach you much more than hacked up solutions found all over the place.
MySQL's implementation of int2str
I provide the mentioned implementation here; the link is here for reference and should be used to read the full implementation.
char *
int2str(long int val, char *dst, int radix,
int upcase)
{
char buffer[65];
char *p;
long int new_val;
char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
ulong uval= (ulong) val;
if (radix < 0)
{
if (radix < -36 || radix > -2)
return NullS;
if (val < 0)
{
*dst++ = '-';
/* Avoid integer overflow in (-val) for LLONG_MIN (BUG#31799). */
uval = (ulong)0 - uval;
}
radix = -radix;
}
else if (radix > 36 || radix < 2)
return NullS;
/*
The slightly contorted code which follows is due to the fact that
few machines directly support unsigned long / and %. Certainly
the VAX C compiler generates a subroutine call. In the interests
of efficiency (hollow laugh) I let this happen for the first digit
only; after that "val" will be in range so that signed integer
division will do. Sorry 'bout that. CHECK THE CODE PRODUCED BY
YOUR C COMPILER. The first % and / should be unsigned, the second
% and / signed, but C compilers tend to be extraordinarily
sensitive to minor details of style. This works on a VAX, that's
all I claim for it.
*/
p = &buffer[sizeof(buffer)-1];
*p = '\0';
new_val= uval / (ulong) radix;
*--p = dig_vec[(uchar) (uval- (ulong) new_val*(ulong) radix)];
val = new_val;
while (val != 0)
{
ldiv_t res;
res=ldiv(val,radix);
*--p = dig_vec[res.rem];
val= res.quot;
}
while ((*dst++ = *p++) != 0) ;
return dst-1;
}
i tried my own implementation of itoa(), it seem's work in binary, octal, decimal and hex
#define INT_LEN (10)
#define HEX_LEN (8)
#define BIN_LEN (32)
#define OCT_LEN (11)
static char * my_itoa ( int value, char * str, int base )
{
int i,n =2,tmp;
char buf[BIN_LEN+1];
switch(base)
{
case 16:
for(i = 0;i<HEX_LEN;++i)
{
if(value/base>0)
{
n++;
}
}
snprintf(str, n, "%x" ,value);
break;
case 10:
for(i = 0;i<INT_LEN;++i)
{
if(value/base>0)
{
n++;
}
}
snprintf(str, n, "%d" ,value);
break;
case 8:
for(i = 0;i<OCT_LEN;++i)
{
if(value/base>0)
{
n++;
}
}
snprintf(str, n, "%o" ,value);
break;
case 2:
for(i = 0,tmp = value;i<BIN_LEN;++i)
{
if(tmp/base>0)
{
n++;
}
tmp/=base;
}
for(i = 1 ,tmp = value; i<n;++i)
{
if(tmp%2 != 0)
{
buf[n-i-1] ='1';
}
else
{
buf[n-i-1] ='0';
}
tmp/=base;
}
buf[n-1] = '\0';
strcpy(str,buf);
break;
default:
return NULL;
}
return str;
}
direct copy to buffer : 64 bit integer itoa hex :
char* itoah(long num, char* s, int len)
{
long n, m = 16;
int i = 16+2;
int shift = 'a'- ('9'+1);
if(!s || len < 1)
return 0;
n = num < 0 ? -1 : 1;
n = n * num;
len = len > i ? i : len;
i = len < i ? len : i;
s[i-1] = 0;
i--;
if(!num)
{
if(len < 2)
return &s[i];
s[i-1]='0';
return &s[i-1];
}
while(i && n)
{
s[i-1] = n % m + '0';
if (s[i-1] > '9')
s[i-1] += shift ;
n = n/m;
i--;
}
if(num < 0)
{
if(i)
{
s[i-1] = '-';
i--;
}
}
return &s[i];
}
note: change long to long long for 32 bit machine. long to int in case for 32 bit integer. m is the radix. When decreasing radix, increase number of characters (variable i). When increasing radix, decrease number of characters (better). In case of unsigned data type, i just becomes 16 + 1.
Here is a much improved version of Archana's solution. It works for any radix 1-16, and numbers <= 0, and it shouldn't clobber memory.
static char _numberSystem[] = "0123456789ABCDEF";
static char _twosComp[] = "FEDCBA9876543210";
static void safestrrev(char *buffer, const int bufferSize, const int strlen)
{
int len = strlen;
if (len > bufferSize)
{
len = bufferSize;
}
for (int index = 0; index < (len / 2); index++)
{
char ch = buffer[index];
buffer[index] = buffer[len - index - 1];
buffer[len - index - 1] = ch;
}
}
static int negateBuffer(char *buffer, const int bufferSize, const int strlen, const int radix)
{
int len = strlen;
if (len > bufferSize)
{
len = bufferSize;
}
if (radix == 10)
{
if (len < (bufferSize - 1))
{
buffer[len++] = '-';
buffer[len] = '\0';
}
}
else
{
int twosCompIndex = 0;
for (int index = 0; index < len; index++)
{
if ((buffer[index] >= '0') && (buffer[index] <= '9'))
{
twosCompIndex = buffer[index] - '0';
}
else if ((buffer[index] >= 'A') && (buffer[index] <= 'F'))
{
twosCompIndex = buffer[index] - 'A' + 10;
}
else if ((buffer[index] >= 'a') && (buffer[index] <= 'f'))
{
twosCompIndex = buffer[index] - 'a' + 10;
}
twosCompIndex += (16 - radix);
buffer[index] = _twosComp[twosCompIndex];
}
if (len < (bufferSize - 1))
{
buffer[len++] = _numberSystem[radix - 1];
buffer[len] = 0;
}
}
return len;
}
static int twosNegation(const int x, const int radix)
{
int n = x;
if (x < 0)
{
if (radix == 10)
{
n = -x;
}
else
{
n = ~x;
}
}
return n;
}
static char *safeitoa(const int x, char *buffer, const int bufferSize, const int radix)
{
int strlen = 0;
int n = twosNegation(x, radix);
int nuberSystemIndex = 0;
if (radix <= 16)
{
do
{
if (strlen < (bufferSize - 1))
{
nuberSystemIndex = (n % radix);
buffer[strlen++] = _numberSystem[nuberSystemIndex];
buffer[strlen] = '\0';
n = n / radix;
}
else
{
break;
}
} while (n != 0);
if (x < 0)
{
strlen = negateBuffer(buffer, bufferSize, strlen, radix);
}
safestrrev(buffer, bufferSize, strlen);
return buffer;
}
return NULL;
}
Where is the itoa function in Linux?
As itoa() is not standard in C, various versions with various function signatures exists.
char *itoa(int value, char *str, int base); is common in *nix.
Should it be missing from Linux or if code does not want to limit portability, code could make it own.
Below is a version that does not have trouble with INT_MIN and handles problem buffers: NULL or an insufficient buffer returns NULL.
#include <stdlib.h>
#include <limits.h>
#include <string.h>
// Buffer sized for a decimal string of a `signed int`, 28/93 > log10(2)
#define SIGNED_PRINT_SIZE(object) ((sizeof(object) * CHAR_BIT - 1)* 28 / 93 + 3)
char *itoa_x(int number, char *dest, size_t dest_size) {
if (dest == NULL) {
return NULL;
}
char buf[SIGNED_PRINT_SIZE(number)];
char *p = &buf[sizeof buf - 1];
// Work with negative absolute value
int neg_num = number < 0 ? number : -number;
// Form string
*p = '\0';
do {
*--p = (char) ('0' - neg_num % 10);
neg_num /= 10;
} while (neg_num);
if (number < 0) {
*--p = '-';
}
// Copy string
size_t src_size = (size_t) (&buf[sizeof buf] - p);
if (src_size > dest_size) {
// Not enough room
return NULL;
}
return memcpy(dest, p, src_size);
}
Below is a C99 or later version that handles any base [2...36]
char *itoa_x(int number, char *dest, size_t dest_size, int base) {
if (dest == NULL || base < 2 || base > 36) {
return NULL;
}
char buf[sizeof number * CHAR_BIT + 2]; // worst case: itoa(INT_MIN,,,2)
char *p = &buf[sizeof buf - 1];
// Work with negative absolute value to avoid UB of `abs(INT_MIN)`
int neg_num = number < 0 ? number : -number;
// Form string
*p = '\0';
do {
*--p = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-(neg_num % base)];
neg_num /= base;
} while (neg_num);
if (number < 0) {
*--p = '-';
}
// Copy string
size_t src_size = (size_t) (&buf[sizeof buf] - p);
if (src_size > dest_size) {
// Not enough room
return NULL;
}
return memcpy(dest, p, src_size);
}
For a C89 and onward compliant code, replace inner loop with
div_t qr;
do {
qr = div(neg_num, base);
*--p = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-qr.rem];
neg_num = qr.quot;
} while (neg_num);
glibc internal implementation
glibc 2.28 has an internal implementation:
stdio-common/_itoa.c
sysdeps/generic/_itoa.h
which is used in several places internally, but I could not find if it can be exposed or how.
At least that should be a robust implementation if you are willing to extract it.
This question asks how to roll your own: How to convert an int to string in C?
I would prefer this: https://github.com/wsq003/itoa_for_linux
It should be the fastest itoa() ever. We use itoa() instead of sprintf() for performance reason, so a fastest itoa() with limited feature is reasonable and worthwhile.
If you just want to print them:
void binary(unsigned int n)
{
for(int shift=sizeof(int)*8-1;shift>=0;shift--)
{
if (n >> shift & 1)
printf("1");
else
printf("0");
}
printf("\n");
}
The replacement with snprintf is NOT complete!
It covers only bases: 2, 8, 10, 16, whereas itoa works for bases between 2 and 36.
Since I was searching a replacement for base 32, I guess I'll have to code my own!
I have used _itoa(...) on RedHat 6 and GCC compiler. It works.
You can use this program instead of sprintf.
void itochar(int x, char *buffer, int radix);
int main()
{
char buffer[10];
itochar(725, buffer, 10);
printf ("\n %s \n", buffer);
return 0;
}
void itochar(int x, char *buffer, int radix)
{
int i = 0 , n,s;
n = s;
while (n > 0)
{
s = n%radix;
n = n/radix;
buffer[i++] = '0' + s;
}
buffer[i] = '\0';
strrev(buffer);
}

Resources