7

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

5 Answers 5

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;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Great, I've removed my now-obsolete comment. :)
anInteger = -anInteger; may fail for INT_MIN
The stringify method is not valid. INT_MIN cannot be defined as a simple decimal string. It must be a nontrivial expression of some sort.
The better approach is to always do your arithmetic with negative numbers, which have larger range, or to convert to an unsigned type in a safe way to do the arithmetic.
INT_MIN requires limits.h.
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;
}

3 Comments

I think this might be a little too complicated, see my answer.
@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.
+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...
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;
}

2 Comments

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
Is there a reason for number = 0 - number; instead of number = -number;?
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.

5 Comments

-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..: 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.
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..: Why not provide a better solution?
The linked implementation is atoi, not itoa.
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.*/

1 Comment

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 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.