Converting Integer to string in C Without sprintf

Discussion in 'C' started by lionaneesh, Mar 16, 2012.

1. lionaneeshActive Member

Joined:
Mar 21, 2010
Messages:
848
224
Trophy Points:
43
Occupation:
Student
Location:
India
Today while solving a problem, I had to convert integers to string in C to use its indexing capabilities. One simple solution was to use sprintf, which can be done in 2-3 lines, but i was temped to solve this problem without any string manipulation functions.

The Code

Code:
// Change a positive integer to a string in C

#include <stdio.h>
#include <stdlib.h>  // for malloc
#include <math.h>  // for pow

int get_number_of_digits(int n)
{
int i, count;
for (i = 10, count = 0; ; i *= 10, count++) {
if ((int)n / i == 0) {
break;
}
}
return count + 1;
}

int main()
{
int number, no_of_digits, prev = 0, i, j;
char *number_string;

scanf("%d", &number);
no_of_digits = get_number_of_digits(number);

number_string = (char *)malloc(sizeof(char) * (no_of_digits + 1)); // +1 for NULL
for (i = 0, j = pow(10, no_of_digits - 1); i < no_of_digits; i++, j /= 10) {
number_string[i] = (number / j - (prev * 10)) + 48;  // int to ascii
prev             = number / j;
}
number_string[i] = '\0';
printf("%s\n", number_string);
}

In the above program we used malloc (for dynamic memory allocation) and pow. I had to look at an ASCII table for reference on how to convert from int to ASCII and rest all is pure logic.

Compiling :

Code:
gcc -lm int_to_str.c -o int_to_str

we used the -lm flag for math libraries

Output:

Code:
lionaneesh@lionaneesh:~/Challenges/\$ ./int_to_str
123
123

2. ScriptingJohn Hoder

Joined:
Jun 29, 2010
Messages:
421
57
Trophy Points:
0
Occupation:
School for life
Location:
/root
Awesome example how flexible C is Very good tut, althouhg I miss some more explanation about the code...

3. sklNew Member

Joined:
May 20, 2012
Messages:
2
0
Trophy Points:
0
A faster and more elegant implementation:

Code:
inline int inttostr( char *s, int n )
{
unsigned int i = 1000000000;
/* largest base 10 'place' < 2^32 */
/* for a 64 bit int - 10000000000000000000 */
/* for a 16 bit int - 10000 */
/* etc */

afterwards, it doesn't matter */

if( ((signed)n) < 0 ) {
*s++ = '-';
n = 0 - n;
}

do
*s++ = '0' + (((n-n%i)/i)%10);
while( i /= 10 );

/* terminating null */

*s = 0;

/* return value should always be zero, unless
there was some unpredicted badness */

return n;
}

comparison:

one million reps of this:

Code:
real	0m0.198s
user	0m0.188s
sys	0m0.000s

vs one million reps of above

Code:
real	0m0.228s
user	0m0.224s
sys	0m0.000s

4. sklNew Member

Joined:
May 20, 2012
Messages:
2
0
Trophy Points:
0
oops ... I did that too quickly without thinking.

should insert the following before the main loop:

Code:
while( i > n ) i /= 10;

i.e.

Code:
int inttostr( char *s, int n )
{
unsigned int i = 1000000000;

if( ((signed)n) < 0 ) {
*s++ = '-';
n = -n;
}

while( i > n ) i /= 10;

do {
*s++ = '0' + (n-n%i)/i%10;
} while( i /= 10 );

*s = 0;

return n;
}

this is actually considerably faster

Code:
real	0m0.112s
user	0m0.104s
sys	0m0.004s

Joined:
May 30, 2012
Messages:
6