2009-02-05 71 views
6

Estoy tratando de convertir un número entero en C en una matriz que contiene cada uno de los dígitos de ese númeroconvertir un número entero en una matriz

es decir, si tengo

int number = 5400 

cómo puedo llegar a

int numberArray[4] 

donde

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

Cualquier sugerencia recibida con gratitud.

Respuesta

13

Esto funcionaría para los números de> = 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; 
} 

EDITAR: Solo un poco más estilo C pero más críptico.

#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; 
} 
+0

¿por qué esta función es un puntero de char? ¿Y qué hace el nuevo char [length]? Parece un puntero al primer índice de la matriz, pero a mi compilador no parece gustarle 'new char' – droseman

+0

'new char' es C++ speak. La forma correcta de hacerlo en C es el segundo bit de código. –

+0

Además, es importante que, al final de su programa, llame a 'free()' en cualquier arreglo que haya obtenido de esta función. De lo contrario, se pierde memoria. –

5

Sugerencia: Eche un vistazo a esta pregunta anterior "Sum of digits in C#". En él se explica cómo extraer los dígitos en el número usando varios métodos, algunos relevante en C.

De 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++; 
} 
1

averiguar el número de dígitos es complicado, pero asumiendo que es siempre 4 dígitos que puede do:

for (i = 0; i < 4; i++) { 
    numberArray[i] = number%10; 
    number = number div 10; 
} 
+1

En C, se llama /, no div. –

+0

No, la cantidad de dígitos es fácil. Solo use log10 (a) + 1. – vava

+0

en algunos casos, seguramente esto evaluaría el valor incorrecto? p.ej. log10 (50) +1 = 2.70 = 3 como un entero. – droseman

0

código C:

/* 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); 

Usted verá el número de dígitos que convirtió tomando la diferencia

digitsp - digits 

Si desea ponerlo en una función:

#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); 
} 

Prefiero el arr automático Esto se aplica a la asignación de memoria dinámica, ya que es más fácil hacerlo bien y no tener fugas accidentales.

+0

"Un poco más de 3 bits?" Creo que acabas de ganar algún tipo de premio de redacción. – unwind

+0

sí, me parece que suena extraño oO déjame cambiarlo –

+0

Impresionante cómo la diferente ruta lógica produce los mismos resultados :) 32/3 + 1 es casi lo mismo que log10 (2 ** 32) + 1 == log2 (2 * * 32)/log2 (10) + 1 == 32/log2 (10) + 1 <32/3 + 1 – vava

1

Si necesita tener en cuenta los números negativos, es posible que necesite alguna lógica adicional. De hecho, cuando juegas con las matrices, no conoces el tamaño inicial, es posible que desees hacer más comprobaciones de seguridad, y agregar una API para manejar la estructura de los datos también es muy útil.

// 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); 

} 
+0

no se requieren números negativos, afortunadamente. Es un contador de horas de conteo. Sin embargo, es posible que este número sea bastante grande. – droseman

6

Puede calcular el número de dígitos en un entero con logaritmo en lugar de un bucle. Por lo tanto,

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; 
} 
+0

+1 Me parece bien –

0

utilizando el código de Vadim, me ocurrió con este programa de prueba:

#include <stdio.h> 
#include <stdlib.h> 
#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; 
} 



int main(void) 
{ 
    int InputNumber; 
    int arr[5]; 

    printf("enter number: \n"); 
    scanf("%d", &InputNumber); 

    convertNumberIntoArray(InputNumber); 

    printf("The number components are: %d %d %d\n", arr[0],arr[1],arr[2]); 

    system("PAUSE");  
    return 0; 
} 

pero la salida es basura. ¿Alguien puede avisar si he hecho algo estúpido aquí?

/***** output *****/ 
enter number: 
501 
The number components are: 2009291924 2009145456 -1 
Press any key to continue . . . 

--Dave

+0

La función devuelve una matriz. Necesitas esto: 'char * arr; arr = convertNumberIntoArray (InputNumber); 'Tenga en cuenta que' arr' debe ser un 'char *', no un 'int []'. Si desea que sea un 'int *', debe cambiar la función para devolver 'int *', no 'char *'. –

+0

gracias Chris, ahora funciona – droseman

+0

no se olvide de liberar (arr) después de que haya terminado con él. Alternativamente, puede usar el enfoque @litb y crear una matriz estática con longitud (32/3 + 1) == 11 y simplemente completarlo. – vava

1

Prueba de esto,

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