7

It is possible to convert integer to string in C without sprintf?

Yousha Aleayoub
  • 4,532
  • 4
  • 53
  • 64

5 Answers5

7

There's a nonstandard function:

char *string = itoa(numberToConvert, 10); // assuming you want a base-10 representation

Edit: it seems you want some algorithm to do this. Here's how in base-10:

#include <stdio.h>

#define STRINGIFY(x) #x
#define INTMIN_STR STRINGIFY(INT_MIN)

int main() {
    int anInteger = -13765; // or whatever

    if (anInteger == INT_MIN) { // handle corner case
        puts(INTMIN_STR);
        return 0;
    }

    int flag = 0;
    char str[128] = { 0 }; // large enough for an int even on 64-bit
    int i = 126;
    if (anInteger < 0) {
        flag = 1;
        anInteger = -anInteger;
    }

    while (anInteger != 0) { 
        str[i--] = (anInteger % 10) + '0';
        anInteger /= 10;
    }

    if (flag) str[i--] = '-';

    printf("The number was: %s\n", str + i + 1);

    return 0;
}
5

Here's an example of how it might work. Given a buffer and a size, we'll keep dividing by 10 and fill the buffer with digits. We'll return -1 if there is not enough space in the buffer.

int
integer_to_string(char *buf, size_t bufsize, int n)
{
   char *start;

   // Handle negative numbers.
   //
   if (n < 0)
   {
      if (!bufsize)
         return -1;

      *buf++ = '-';
      bufsize--;
   }

   // Remember the start of the string...  This will come into play
   // at the end.
   //
   start = buf;

   do
   {
      // Handle the current digit.
      //
      int digit;
      if (!bufsize)
         return -1;
      digit = n % 10;
      if (digit < 0)
         digit *= -1;
      *buf++ = digit + '0';
      bufsize--;
      n /= 10;
   } while (n);

   // Terminate the string.
   //
   if (!bufsize)
      return -1;
   *buf = 0;

   // We wrote the string backwards, i.e. with least significant digits first.
   // Now reverse the string.
   //
   --buf;
   while (start < buf)
   {
      char a = *start;
      *start = *buf;
      *buf = a;
      ++start;
      --buf;
   }

   return 0;
}
asveikau
  • 39,039
  • 2
  • 53
  • 68
  • I think this might be a little too complicated, see my answer. –  Aug 05 '12 at 21:02
  • 1
    @H2CO3 - I kind of like mine. I know that 128 bytes is "good enough for anyone" but checking buffer sizes is a good habit. I also like writing at the start of the buffer instead of the end. – asveikau Aug 05 '12 at 21:10
  • +1, I definitely prefer a buffer-size-aware solution, rather than a blatantly preallocated, fixed buffer with an arbitrary "big enough" size. OTOH, this could indeed do with some streamlining... – Sz. Jan 28 '16 at 20:23
4

Unfortunately none of the answers above can really work out in a clean way in a situation where you need to concoct a string of alphanumeric characters.There are really weird cases I've seen, especially in interviews and at work.

The only bad part of the code is that you need to know the bounds of the integer so you can allocate "string" properly.

In spite of C being hailed predictable, it can have weird behaviour in a large system if you get lost in the coding.

The solution below returns a string of the integer representation with a null terminating character. This does not rely on any outer functions and works on negative integers as well!!

#include <stdio.h>
#include <stdlib.h>


void IntegertoString(char * string, int number) {

   if(number == 0) { string[0] = '0'; return; };
   int divide = 0;
   int modResult;
   int  length = 0;
   int isNegative = 0;
   int  copyOfNumber;
   int offset = 0;
   copyOfNumber = number;
   if( number < 0 ) {
     isNegative = 1;
     number = 0 - number;
     length++;
   }
   while(copyOfNumber != 0) 
   { 
     length++;
     copyOfNumber /= 10;
   }

   for(divide = 0; divide < length; divide++) {
     modResult = number % 10;
     number    = number / 10;
     string[length - (divide + 1)] = modResult + '0';
   }
   if(isNegative) { 
   string[0] = '-';
   }
   string[length] = '\0';
}

int main(void) {


  char string[10];
  int number = -131230;
  IntegertoString(string, number);
  printf("%s\n", string);

  return 0;
}
  • 1
    I like yours the best. However in the 0 case you do not terminate the string, so it just works by luck in most cases. `string[1] = 0;` is needed – Joakim Jan 08 '16 at 23:13
  • Is there a reason for `number = 0 - number;` instead of `number = -number;`? – Sz. Jan 28 '16 at 19:59
3

You can use itoa where available. If it is not available on your platform, the following implementation may be of interest:

https://web.archive.org/web/20130722203238/https://www.student.cs.uwaterloo.ca/~cs350/common/os161-src-html/atoi_8c-source.html

Usage:

char *numberAsString = itoa(integerValue); 

UPDATE

Based on the R..'s comments, it may be worth modifying an existing itoa implementation to accept a result buffer from the caller, rather than having itoa allocate and return a buffer.

Such an implementation should accept both a buffer and the length of the buffer, taking care not to write past the end of the caller-provided buffer.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • 1
    -1, `itoa` is not only non-standard, but uses a static buffer, rendering any code that uses it not only non-thread-safe but subject to having the result clobbered elsewhere if it doesn't immediately copy the result. Doing this right is almost a one-liner, so bad solutions like this should never be used. – R.. GitHub STOP HELPING ICE Aug 05 '12 at 21:50
  • @R..: I did mention that you can use itoa *where available*, and provided an implementation in case it is not available on a given platform. The OP did not state any thread safety requirements. However, if thread safety is required, converting the static buffer to thread allocated storage or heap based storage is trivial. Still, I went ahead and replaced the linked implementation with one that does not use a static buffer. – Eric J. Aug 05 '12 at 22:23
  • There are still plenty of ways you could do this right with the result going in a caller-provided buffer. The majority of the problem with `itoa` is not that it's nonstandard (as you showed us, a drop-in replacement is trivial to give); the problem is that it's a bad api design because it returns static storage. – R.. GitHub STOP HELPING ICE Aug 05 '12 at 22:53
  • @R..: Why not provide a better solution? – Eric J. Aug 05 '12 at 23:09
  • The linked implementation is `atoi`, not `itoa`. – Emil Laine Jan 18 '17 at 21:47
0
    int i = 24344; /*integer*/
    char *str = itoa(i); 
    /*allocates required memory and 
    then converts integer to string and the address of first byte of memory is returned to str pointer.*/
Rahul Raina
  • 3,322
  • 25
  • 30
  • 1
    There was already posted 3 years ago an answer suggesting usage of __itoa__ which is still not a standard function in C/C++. For example take a look on [itoa](http://www.cplusplus.com/reference/cstdlib/itoa/) on __C++ reference__ website and it can be seen that __itoa__ explained there has 3 parameters whereby one must be a pointer to a string buffer being large enough for the integer as string. So no dynamic memory allocation for the string. – Mofi May 16 '15 at 16:51