2

I want to know how to get number to string without standard C or C++ functions, for example:

char str[20];
int num = 1234;
// How to convert that number to string (str)?

Thanks.

4
  • Look at this answer Commented Nov 8, 2013 at 17:54
  • 1
    Hint: divide by ten in a loop, each division gives you a digit. And '0' + 2 = '2' As Chad points out, you'll need a division and a modulo ( % ). By this time, probably someone already did it for you. Commented Nov 8, 2013 at 17:54
  • @CharlieBurns, mod and divide are both necessary :) Commented Nov 8, 2013 at 17:55
  • @Chad mod and div aren't necessary for converting to a binary, octal or hexadecimal string, just for a decimal string (the radix was not specified) and other non-powers-of-2 Commented Nov 8, 2013 at 18:07

5 Answers 5

2

Using C (not C++)

Assuming you're preallocating your buffer for str as in your question:

char *itostr(int num, char *str) {
    int len = 1;
    long tmp = num;
    int sign = num < 0;
    if (sign) {
        str[0] = '-';
        tmp = -tmp;
    }
    while (num/=10) ++len;
    str[len+sign] = 0;
    while (len--) {
        str[len+sign] = '0'+tmp%10;
        tmp /= 10;
    }
    return str;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Fails for a 2s compliment INT_MIN.
Thanks for catching that, @chux. The code is now edited to work for all cases, including INT_MIN. (Assumption is that sizeof long > sizeof int.)
Later note: If sizeof long == sizeof int then declare tmp to be long long (C99 and later).
Your later note works when sizeof long long > size int, but not when they are the same size. Certainly true in most implementations.
@chux, agreed! We must always be aware of datatype sizes on our target platforms or else be prepared to #define smart conditional handling of them! Cheers.
2

To get the lowest digit, use num % 10. To convert a digit to a character, add '0'. To remove the lowest digit after you've handled it, divide by 10: num /= 10;. Repeat until done.

Comments

0

Convert it char by char, e.g. the last char of the string is '4', the previous one is '3' and so on. Use math to determine the chars, it might be easier to create "4321" string and then rotate it.

Comments

0

An "after accepted answer" that works for all int including INT_MIN.

static char *intTostring_helper(int i, char *s) {
  if (i < -9) {
    s = intTostring_helper(i/10, s);
  }
  *s++ = (-(i%10)) + '0' ;
  return s;
}

char *intTostring(int i, char *dest) {
  char *s = dest;
  if (i < 0) {  // If non 2s compliment, change to some IsSignBitSet() function.
    *s++ = '-';
  }
  else {
    i = -i;
  }
  s = intTostring_helper(i, s);
  *s = '\0';
  return dest;
}

Comments

-1

A simplistic way to do this is to leave a lot of leading zeros. I like it because it uses only basic code, and doesn't require any dynamic memory allocation. It should consequently also be very fast:

char * convertToString(int num, str) {
    int val;

    val = num / 1000000000; str[0] = '0' + val; num -= val * 1000000000;
    val = num / 100000000;  str[1] = '0' + val; num -= val * 100000000;
    val = num / 10000000;   str[2] = '0' + val; num -= val * 10000000;
    val = num / 1000000;    str[3] = '0' + val; num -= val * 1000000;
    val = num / 100000;     str[4] = '0' + val; num -= val * 100000;
    val = num / 10000;      str[5] = '0' + val; num -= val * 10000;
    val = num / 1000;       str[6] = '0' + val; num -= val * 1000;
    val = num / 100;        str[7] = '0' + val; num -= val * 100;
    val = num / 10;         str[8] = '0' + val; num -= val * 10;
    val = num;              str[9] = '0' + val;
                            str[10] = '\0';

    return str;
}

Of course, there are tons of tweaks you could do to this - modifying the way the destination array gets created is possible, as is adding a boolean that says to trim leading 0s. And we could make this much more efficient using a loop. Here's in improved method:

void convertToStringFancier(int num, char * returnArrayAtLeast11Bytes, bool trimLeadingZeros) {
    int divisor = 1000000000;
    char str[11];
    int i;
    int val;

    for (i = 0; i < 10; ++i, divisor /= 10) {
        val = num / divisor;
        str[i] = '0' + val;
        num -= val * divisor;
    }
    str[i] = '\0';

    // Note that everything below here is just to get rid of the leading zeros and copy the array, which is longer than the actual number conversion.
    char * ptr = str;
    if (trimLeadingZeros) {
        while (*ptr == '0') { ++ptr; }
        if (*ptr == '\0') { // handle special case when the input was 0
            *(--ptr) = '0';
    }
    for (i = 0; i < 10 && *ptr != '\0'; ++i) {
    while (*ptr != '\0') {
        returnArrayAtLeast11Bytes[i] = *ptr;
    }
    returnArrayAtLeast11Bytes[i] = '\0';
}

4 Comments

When returning a pointer to private storage, make sure it has a storage class other than automatic. I've added the static keyword that accomplishes this. Do note, of course, that the result is not thread-safe in the sense that two threads will collide in their use of the same private storage.
@RBerteig Frankly, I left it in there since I was already spoon feeding an answer for what seemed likely to be a homework problem. I left a comment in there, but left room (at least in the first solution) for the poster to apply their own solution. The C standard has changed significantly since I was avidly using it, but at least back then, it's perfectly acceptable to return stack storage, as long as it gets used or copied before anything else modifies the stack.
I agree the OP is clearly a homework problem. However, while returning pointers to automatics may have worked, it was never really sanctioned. The problem even in the early days was with knowing that nothing could have modified that bit of the stack yet. All that said, I still argue that an answer that contains a known bug doesn't help SO the site. There may be little hope for the original poster, of course. I'm more concerned about next-year's class using Google more cleverly (aka using it at all) and getting a wrong answer....
@RBerteig I think we'd both agree that the set of future users who will search Google, read past the accepted answer to mine, read my code and like it enough to copy it - without noting the comments I had left inline about a bad programming practice - is very small. Still, I understand what you're saying about making it highly workable for future generations, so I removed the offending code. Of course, the code now has the assumption that the consumer of the function will pass an array of sufficient size. Whether threading/statics, array size, or automatics, there's always some tradoff...

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.