2011-12-29 20 views

Respuesta

4

En lo que sigue supongo que quiere decir dígitos decimales (base 10). Probablemente pueda adaptar las soluciones a otros sistemas numéricos sustituyendo el 10 s.

Tenga en cuenta que el funcionamiento del módulo es algo complicado respecto a los operandos negativos. Por lo tanto, he elegido el tipo de datos para que sea un entero sin signo.

Si desea procesar el dígito menos significativo en primer lugar, puede probar con el siguiente método no probado:

uint32_t n = 1191223; 
do { 
    uint32_t digit = n%10; 
    // do something with digit 
} 
while (n/=10); 

Si prefiere caminar por los dígitos a partir del dígito más significativo, se podría tratar de adaptar el siguiente código no probado:

uint32_t n = 1191223; 
#define MAX_DIGITS 10 // log10((double)UINT32_MAX)+1 
uint32_t div = pow(10, MAX_DIGITS); 

// skip the leading zero digits 
while (div && !(n/div)) div/=10; 
if (!div) div = 10; // allow n being zero 

do { 
    uint32_t digit = (n/div)%10; 
    // do something with digit 
} 
while (div/=10); 
0

Algo como esto:

char data[128]; 
int digits = 1191223; 
sprintf(data, "%d", digits); 
int length = strlen(data); 
for(int i = 0; i < length; i++) { 
    // iterate through each character representing a digit 
} 

Tenga en cuenta que si utiliza un número octal como 0100 también necesita cambiar el sprintf(data, "%d", digits); al .

+0

Krister, si mi inicio de dígitos es "0" me da una longitud incorrecta, ¿sabría por qué? Por cierto, a la gente le gustan todas las respuestas anteriores. – kforkarim

+0

@kforkarim - Agregué una actualización para manejar números octales - números que comienzan con '0' – Cyclonecode

3

Quiere iterar sobre los dígitos de la base 10, pero un número entero no tiene ningún concepto de anotación y dígitos arábigos. Convertirlo en una cadena en primer lugar:

int i = 1191223; 
char buffer[16]; 
char *j; 
snprintf(buffer, 16, "%i", i); 
for (j = buffer; *j; ++j) { /* digit is in *j - '0' */ } 
+0

thiton Solo tengo curiosidad ¿A qué te refieres aquí con * j - '0', ¿evita el primer 0? Estaba intentando esto con un dígito de 0191223 y la longitud no es correcta, ¿alguna sugerencia? – kforkarim

+1

@kforkarim probablemente esa es la conversión 'char2int':' uint32_t digit = * j-'0 '; '. Asegúrese de manejar el ''-'' que la cadena puede contener. – moooeeeep

0

Una forma hacker es convertir esto a la cadena (ver strtol) y luego reconvertir a un número. usted podría utilizar algo como character you want - '0'

0

De la parte superior de mi cabeza: "i% 100000", "i% 100000", ...

Una solución recursiva dejaría que se parte de "i% 10" .

1

Puede utilizar sprintf() para convertirlo en una matriz char, y luego recorrer que, como tal (no probado, solo para empezar):

int a = 1191223; 
char arr[16]; 
int rc = sprintf(arr, "%d", a); 

if (rc < 0) { 
    // error 
} 

for (int i = 0; i < rc; i++) { 
    printf("digit %d = %d\n", i, arr[i]); 
} 
1
void access_digits(int n) 
{ 
     int digit; 
     if (n < 0) n = -n; 
     do { 
       digit = n % 10; 
       /* Here you can do whatever you 
        want to do with the digit */ 
     } while ((n/=10) > 0); 
} 
8

delante, o al revés?

Suponiendo un número entero positivo:

unsigned int n = 1191223; 

    while (n != 0) { 
     doSomething (n % 10); 
     n /= 10; 
    } 

... trabajará menor a mayor, o ...

EDITAR me había olvidado de esta solución no laborable que tuve aquí.Tenga en cuenta que Very Smart People ™ parece usar la iteración más pequeña a la más grande de manera consistente (tanto el kernel de Linux como el printf de GLibC, por ejemplo, simplemente iteran hacia atrás) pero esta es una manera horrible de hacerlo si realmente no desea usar snprintf por alguna razón ...

int left_to_right (unsigned int n) { 
    unsigned int digit = 0; 

    if (0 == n) { 
    doSomething (0); 
    } else { 
    digit = pow(10, 1.0+ floor(log10(n))); 
    while (digit /= 10) { 
     doSomething ((n/digit) % 10); 
    } 
    } 
} 

asumo que es muy tonto suponer que usted tiene log10 y pow pero no snprintf, por lo que un plan alternativo sería

int left_to_right_fixed_max (unsigned int n) { 
    unsigned int digit = 1000000000; /* make this very big */ 
    unsigned int n10 = 10 * n; 

    if (0 == n) { 
    doSomething (0); 
    } else { 
    while (digit > n10) { digit /= 10; } 
    while (digit /= 10) { 
     doSomething ((n/digit) % 10); 
    } 
    } 
} 

... o, si realmente don' t tiene hardware multiplicar/dividir, puede recurrir al uso de capaz de poderes de diez.

int left_to_right (unsigned int n) { 
    static const unsigned int digit [] = 
    { 1, 
     10, 
     100, 
     1000, 
     10000, 
     100000, 
     1000000, 
     10000000, 
     100000000, 
     1000000000 /* make this very big */ 
    }; 
    static const unsigned char max_place = 10; 
    /* length of the above array */ 

    unsigned char decimal; 
    unsigned char place; 
    unsigned char significant = 0; /* boolean */ 

    if (0 == n) { 
    doSomething (0); 
    } else { 
    place = max_place; 
    while (place--) { 
     decimal = 0; 
     while (n >= digit[place]) { 
     decimal++; 
     n -= digit[place]; 
     } 
     if (decimal | significant) { 
     doSomething (decimal); 
     significant |= decimal; 
     } 
    } 
    } 
} 

... que he adaptado de http://www.piclist.com/techref/language/ccpp/convertbase.htm en una versión algo más de uso general.

+0

su primera versión es de atrás hacia adelante, cómo obtiene los dígitos desde adelante y hacia arriba como 1234> 1 2 3 y luego 4 en lugar de 4 3 2 y 1 ... gracias – kforkarim

+0

la iteración funciona bien para adelante pero su omisión cero, cualquier idea de por qué está haciendo eso? – kforkarim

+0

Guau, estoy seguro de que hice un estúpido descuido. Esta noche echaré un vistazo. :-(¡tontamente solo lo intenté con "1191123!" – BRFennPocock

Cuestiones relacionadas