Tengo un número entero como 1191223 y quiero iterar sobre los dígitos. No estoy seguro de cómo hacer esto en C, ¿hay alguna manera fácil de hacer esto?Iteración a través de dígitos en número entero en C
Gracias.
Tengo un número entero como 1191223 y quiero iterar sobre los dígitos. No estoy seguro de cómo hacer esto en C, ¿hay alguna manera fácil de hacer esto?Iteración a través de dígitos en número entero en C
Gracias.
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);
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 .
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' */ }
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
@kforkarim probablemente esa es la conversión 'char2int':' uint32_t digit = * j-'0 '; '. Asegúrese de manejar el ''-'' que la cadena puede contener. – moooeeeep
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'
De la parte superior de mi cabeza: "i% 100000", "i% 100000", ...
Una solución recursiva dejaría que se parte de "i% 10" .
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]);
}
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);
}
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.
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
la iteración funciona bien para adelante pero su omisión cero, cualquier idea de por qué está haciendo eso? – kforkarim
Guau, estoy seguro de que hice un estúpido descuido. Esta noche echaré un vistazo. :-(¡tontamente solo lo intenté con "1191123!" – BRFennPocock
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
@kforkarim - Agregué una actualización para manejar números octales - números que comienzan con '0' – Cyclonecode