noMAD
noMAD

Reputation: 7844

Converting int to int[] in 'C'

I basically want to convert a given int number and store individual digits in an array for further processing. I know I can use % and get each digit and store it. But the thing is if I do not know the number of digits of the int till runtime and hence I cannot allocate the size of the array. So, I cannot work backwards (from the units place). I also do not want to first store the number backwords in an array and then again reverse the array. Is there any other way of getting about doing this?

Eg: int num = 12345; OUTPUT: ar[0] = 1, ar[1] = 2 and so on, where ar[] is an int array.

Upvotes: 2

Views: 1235

Answers (6)

paxdiablo
paxdiablo

Reputation: 881403

The following complete program shows one way to do this. It uses unsigned integers so as to not have to worry about converting - you didn't state what should happen for negative numbers so, like any good consultant, I made the problem disappear for my own convenience :-)

It basically works out the required size of an array and allocates it. The array itself has one element at the start specifying how many elements are in the array (a length int).

Each subsequent element is a digit in sequence. The main code below shows how to process it.

If it can't create the array, it'll just give you back NULL - you should also remember to free the memory passed back once you're done with it.

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

int *convert (unsigned int num) {
    unsigned int *ptr;
    unsigned int digits = 0;
    unsigned int temp = num;

    // Figure out how many digits in the number.
    if (temp == 0) {
        digits = 1;
    } else {
        while (temp > 0) {
            temp /= 10;
            digits++;
        }
    }

    // Allocate enough memory for length and digits.
    ptr = malloc ((digits + 1) * sizeof (unsigned int));

    // Populate array if we got one.
    if (ptr != NULL) {
        ptr[0] = digits;
        for (temp = 0; temp < digits; temp++) {
            ptr[digits - temp] = num % 10;
            num /= 10;
        }
    }
    return ptr;
}

That convert function above is the "meat" - it allocates an integer array to place the length (index 0) and digits (indexes 1 through N where N is the number of digits). The following was the test program I used.

int main (void) {
    int i;
    unsigned int num = 12345;
    unsigned int *arr = convert (num);

    if (arr == NULL) {
        printf ("No memory\n");
    } else {
        // Length is index 0, rest are digits.

        for (i = 1; i <= arr[0]; i++)
            printf ("arr[%d] = %u\n", i, arr[i]);
        free (arr);
    }

    return 0;
}

The output of this is:

arr[1] = 1
arr[2] = 2
arr[3] = 3
arr[4] = 4
arr[5] = 5

Upvotes: 1

Jens Gustedt
Jens Gustedt

Reputation: 78903

What you basically want to do is to transform your integer to an array of its decimal positions. The printf family of functions perfectly knows how to do this, no need to reinvent the wheel. I am changing the assignment a bit since you didn't say anything about signs, and it simply makes more sense for unsigned values.

unsigned* res = 0;
size_t len = 0;
{
  /* temporary array, large enough to hold the representation of any unsigned */
  char positions[20] = { 0 };
  sprintf(position, "%u", number);
  len = strlen(position);
  res = malloc(sizeof(unsigned[len]));
  for (size_t i = 0; i < len; ++i)
    res[i] = position[i] - '0';
}

Upvotes: 0

Dmitri
Dmitri

Reputation: 9375

You can find out the number of digits by taking the base-10 logarithm and adding one. For that, you could use the log10 or log10f functions from the standard math library. This may be a bit slower, but it's probably the most exact as long as double has enough bits to exactly represent your number:

int numdigits = 1 + log10(num);

Alternatively, you could repeatedly divide by ten until the result is zero and count the digits that way.

Still another option is just to allocate enough room for the maximum number of digits the type can have. For a 32-bit integer, that'd be 10; for 64-bit, 20 should be enough. You can just zero the extra digits. Since that's not a lot of wasted space even in the worst case, it might be the simplest and fastest option. You'd have to know how many bits are in an int in your setup, though.

You can also estimate fairly well by allocating 3 digits for each 10 bits used, plus one. That should be enough digits unless the number of bits is ridiculously large (way above the number of digits any of the usual int types could have).

int numdigits = 1
unsigned int n = num;
for (n = num; n & 0x03ff; n >>= 10) 
  numdigits += 3;
/* numdigits is at least the needed number of digits, maybe up to 3 more */

This last one won't work (directly) if the number is negative.

Upvotes: 0

aleph_null
aleph_null

Reputation: 5786

Convert is probably not the right word. You can take the int, dynamically allocate a new int[], and then store the digits of the int into the int[]. I'm using log base 10 to calculate how many digits num has. Include math.h to use it. The following code is untested, but will give you an idea of what to do.

int num = 12345;
int size = (int)(log10(num)+1);

// allocate array
int *digits = (int*)malloc(sizeof(int) * size);

// get digits
for(int i=size-1; i>=0; --i) {
  digits[i] = num%10;
  num=num/10; // integer division
}

Upvotes: 4

Johan Bezem
Johan Bezem

Reputation: 2585

If you have a 32-bit integer type, the maximum value will be comprised of 10 digits at the most (excluding the sign for negative numbers). That could be your upper limit.

If you need to dynamically determine the minimum sufficient size, you can determine that with normal comparisons (since calling a logarithmic function is probably more expensive, but a possibility):

size = 10;
if (myint < 1000000000) size--;
if (myint < 100000000) size--;
/* ... */

Declaring the array to be of a dynamic size depends on the C language standard you are using. In C89 dynamic array sizes (based on values calculated during run-time) is not possible. You may need to use dynamically allocated memory.

HTH,

Johan

Upvotes: 1

Dan Kruchinin
Dan Kruchinin

Reputation: 3045

The easiest way is to calculate number of digits to know the size of an array you need

int input = <input number>; // >= 0
int d, numdigits = 1;
int *arr;

d = input;
while (d /= 10)
   numdigits++;

arr = malloc(sizeof(int) * numdigits);

There's even easier way: probably you pass a number to your program as an argument from command line. In this case you receive it as a string in argp[N], so you can just call strlen(argp[N]) to determine number of digits in your number.

Upvotes: 1

Related Questions