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
Awesome example how flexible C is Very good tut, althouhg I miss some more explanation about the code...
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 */ /* if we are signed, put the sign in the string; 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
oops ... I did that too quickly without thinking. above inserts leading zeroes! 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