11

I am trying to convert an integer number in C into an array containing each of that number's digits

i.e. if I have

int number = 5400

how can I get to

int numberArray[4]

where

numberArray[0] = 0;
numberArray[1] = 0;
numberArray[2] = 4;
numberArray[3] = 5;

Any suggestions gratefully received.

8 Answers 8

18

Hint: Take a look at this earlier question "Sum of digits in C#". It explains how to extract the digits in the number using several methods, some relevant in C.

From Greg Hewgill's answer:

/* count number of digits */
int c = 0; /* digit position */
int n = number;

while (n != 0)
{
    n /= 10;
    c++;
}

int numberArray[c];

c = 0;    
n = number;

/* extract each digit */
while (n != 0)
{
    numberArray[c] = n % 10;
    n /= 10;
    c++;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Pure and simple!
15

This would work for numbers >= 0

#include <math.h>

char * convertNumberIntoArray(unsigned int number) {
    int length = (int)floor(log10((float)number)) + 1;
    char * arr = new char[length];
    int i = 0;
    do {
        arr[i] = number % 10;
        number /= 10;
        i++;
    } while (number != 0);
    return arr;
}

EDIT: Just a little bit more C style but more cryptic.

#include <math.h>

char * convertNumberIntoArray(unsigned int number) {
    unsigned int length = (int)(log10((float)number)) + 1;
    char * arr = (char *) malloc(length * sizeof(char)), * curr = arr;
    do {
        *curr++ = number % 10;
        number /= 10;
    } while (number != 0);
    return arr;
}

5 Comments

why is this function a char pointer ? And what does new char[length] do? It looks like a pointer to the first index of the array, but my compiler doesn't seem to like 'new char'
'new char' is C++speak. The proper way to do it in C is the second bit of code.
Also, it's important that, at the end of your program, you call free() on whatever array you got back from this function. Otherwise you leak memory.
Shouldn't this be returning int *?
It might but there's no reason to use 4 byte int to store 4 bit digit. Char is just more compact way to do that, although it could easily be substituted to ints.
9

You could calculate the number of digits in an integer with logarithm rather than a loop. Thus,

int * toArray(int number)
{
    int n = log10(number) + 1;
    int i;
    int *numberArray = calloc(n, sizeof(int));
    for ( i = 0; i < n; ++i, number /= 10 )
    {
        numberArray[i] = number % 10;
    }
    return numberArray;
}

Comments

2

Try this,

void initialise_array(int *a, int size, int num) {
    for (int i = 0; i < size; ++i, num /= 10)
        a[(size - 1) - i] = num % 10;
}

Comments

2
#include <stdio.h>
#include <string.h>

int main(void)
{
  int i, inputNumber;
  char* charArray;

  printf("\nEnter number: ");
  scanf("%d", &inputNumber);

  /* converts int to print buffer which is char array */
  sprintf(charArray, "%d", inputNumber); 
  int size = strlen(charArray);

  int intArray[size];

  for (i = 0; i < size; i++)
  {
    intArray[i] = charArray[i] - '0';
  }

  return 0;
}

Comments

1

If you need to take negative numbers into account, you might need some extra logic. In fact, when playing around with arrays you don't know the size of upfront, you may want to do some more safety checking, and adding an API for handling the structure of the data is quite handy too.

// returns the number of digits converted
// stores the digits in reverse order (smalles digit first)
// precondition: outputdigits is big enough to store all digits.
//
int convert( int number, int* outputdigits, int* signdigit ) {

  int* workingdigits = outputdigits;

  int sign = 1;
  if( number < 0 ) { *signdigit = -1; number *= -1; }
  ++workingdigits;

  for ( ; number > 0; ++ workingdigits ) {
    *workingdigits = number % 10;
    number = number / 10;
  }

  return workingdigits - outputdigits;
}

void printdigits( int* digits, int size, int signdigit ) {
  if( signdigit < 0 ) printf( "-" );

  for( int* digit = digits+size-1; digit >= digits; --digit ){
    printf( "%d", *digit );
  }
}

int main() {
   int digits[10];
   int signdigit;
   printdigits( digits, convert( 10, digits, &signdigit ), signdigit );
   printdigits( digits, convert( -10, digits, &signdigit ), signdigit );
   printdigits( digits, convert( 1005, digits, &signdigit ), signdigit );

}

1 Comment

no negative numbers required, fortunately. Its an upcounting hours counter. It is possible that this number could get quite large, though.
0

C code:

/* one decimal digit takes a few more than 3 bits. (2^3=8, 2^4=16) */
int digits[(sizeof (int) * CHAR_BIT) / 3 + 1], 
    *digitsp = digits;
do {
    *digitsp++ = number % 10;
    number /= 10;
} while(number > 0);

You will see how many digits you converted by taking the difference

digitsp - digits

If you want to put it into a function:

#define MIN_DIGITS_IN_INT ((sizeof (int) * CHAR_BIT) / 3 + 1)

int to_array(int number, int *digits) {
    int *digitsp = digits;
    do {
        *digitsp++ = number % 10;
        number /= 10;
    } while(number > 0);
    return digitsp - digits;
}

int main() {
    int number = rand();
    int digits[MIN_DIGITS_IN_INT];
    int n = to_array(number, digits);

    /* test whether we're right */
    while(n-- > 0) 
        printf("%d", digits[n]);
    }
    printf(" = %d\n", number);
}

I prefer automatic arrays to dynamic memory allocation in this case, since it's easier to do it right and not leak accidentally.

6 Comments

"A bit more than 3 bits?" I think you just won some kind of phrasing prize.
yeah, i figure it sounds strange oO let me change it
Awesome how different logic path produces the same results :) 32 / 3 + 1 is almost the same as log10(2 ** 32) + 1 == log2(2 ** 32) / log2(10) + 1 == 32 / log2(10) + 1 < 32 / 3 + 1
can u explain MIN_DIGITS_IN_INT ((sizeof (int) * CHAR_BIT) / 3 + 1) ?
rajKumar, it needs to be a compile time constant. so i didn't use log10. you need 3.32193 bits to store one decimal place (ld(10)) - ten binary decisions. that means, that you cannot store more than (sizeof (int) * CHAR_BIT)/3.32193 places in an int, which is 9.63296
|
0

The question as asked has an array of a fixed size and assumes you know and will limit the maximum value of number.

If this is the case a simple recursive routine will work.

void int2a(int * ptr, int input) {
    *ptr = input % 10;
    if (input < 10) return;
    int2a(ptr+1,input/10);
}

and called like this:

    int2a(&num_array[0],number);

If you want the digits reversed in the array order pass the pointer to the last entry in the array and change ptr+1 to ptr-1.

I use this if I want to store a permutation in a readable form, like 127635894. Then in my program I convert to an array of zero based indices which means I have to subtract 1. I end up with the array:

{0,1,6,5,2,4,7,8,3}

Starting one based fixes the number of digits to always be nine.

Comments

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.