cast - convertir un numero char a int
Conversión de Char a int en C (10)
Como los códigos ASCII para ''0'', ''1'', ''2'' .... se colocan de 48 a 57, son esencialmente continuos. Ahora las operaciones aritméticas requieren la conversión de tipo de datos char a int tipo de datos. Por lo que básicamente está haciendo es: 53-48 y, por lo tanto, almacena el valor 5 con el que puede realizar operaciones enteras. Tenga en cuenta que al convertir de nuevo de int a char la el compilador no da error pero solo realiza una operación de módulo 256 para poner el valor en su rango aceptable
Si quiero convertir un solo char
numérico a su valor numérico, por ejemplo, si:
char c = ''5'';
y quiero que c
tenga 5
lugar de ''5''
, ¿es 100% portátil haciéndolo así?
c = c - ''0'';
Escuché que todos los juegos de caracteres almacenan los números en orden consecutivo así que lo asumo, pero me gustaría saber si hay una función de biblioteca organizada para hacer esta conversión, y cómo se hace de forma convencional. Soy un verdadero principiante :)
Como otros han sugerido, pero envuelto en una función:
int char_to_digit(char c) {
return c - ''0'';
}
Ahora solo usa la función. Si, en el futuro, decide utilizar un método diferente, solo necesita cambiar la implementación (rendimiento, diferencias de juegos de caracteres, lo que sea), no necesitará cambiar las personas que llaman.
Esta versión supone que c contiene un carácter que representa un dígito. Puede verificarlo antes de llamar a la función, utilizando la función isdigit de ctype.h.
Como solo está convirtiendo un carácter, la función atoi () es exagerada. atoi () es útil si está convirtiendo representaciones de cadena de números. Las otras publicaciones han dado ejemplos de esto. Si leo tu publicación correctamente, solo estás convirtiendo un carácter numérico. Por lo tanto, solo va a convertir un carácter que sea el rango de 0 a 9. En el caso de convertir solo un carácter numérico, su sugerencia de restar ''0'' le dará el resultado que desea. La razón por la que esto funciona es porque los valores ASCII son consecutivos (como usted dijo). Por lo tanto, restar el valor ASCII de 0 (valor ASCII 48 - ver tabla ASCII para los valores) de un carácter numérico dará el valor del número. Entonces, su ejemplo de c = c - ''0'' donde c = ''5'', lo que realmente está sucediendo es 53 (el valor ASCII de 5) - 48 (el valor ASCII de 0) = 5.
Cuando publiqué esta respuesta por primera vez, no tomé en consideración tu comentario acerca de ser 100% portátil entre diferentes conjuntos de caracteres. Seguí mirando alrededor y parece que tu respuesta sigue siendo en su mayoría correcta. El problema es que está usando un char que es un tipo de datos de 8 bits. Lo cual no funcionaría con todos los tipos de caracteres. Lee este artículo de Joel Spolsky en Unicode para obtener mucha más información sobre Unicode. En este artículo, dice que usa wchar_t para los personajes. Esto ha funcionado bien para él y publica su sitio web en 29 idiomas. Entonces, necesitarías cambiar tu char a wchar_t. Aparte de eso, dice que el personaje bajo el valor 127 y más abajo es básicamente el mismo. Esto incluiría personajes que representan números. Esto significa que la matemática básica que propones debería funcionar para lo que estabas tratando de lograr.
Normalmente, si no hay garantía de que su entrada esté en el rango ''0'' ... ''9'', deberá realizar una comprobación como esta:
if (c >= ''0'' && c <= ''9'') {
int v = c - ''0'';
// safely use v
}
Una alternativa es usar una tabla de búsqueda. Usted obtiene una verificación y conversión de rango simple con menos (y posiblemente más rápido) código:
// one-time setup of an array of 256 integers;
// all slots set to -1 except for ones corresponding
// to the numeric characters
static const int CHAR_TO_NUMBER[] = {
-1, -1, -1, ...,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // ''0''..''9''
-1, -1, -1, ...
};
// Now, all you need is:
int v = CHAR_TO_NUMBER[c];
if (v != -1) {
// safely use v
}
PD. Sé que esto es una exageración . Solo quería presentarlo como una solución alternativa que puede no ser inmediatamente evidente.
Prueba esto :
char c = ''5'' - ''0'';
Puede usar atoi
, que es parte de la biblioteca estándar.
Sí, esta es una conversión segura. C requiere que funcione. Esta garantía se encuentra en la sección 5.2.1, párrafo 2, del último estándar ISO C, cuyo borrador reciente es N1570 :
Tanto los conjuntos de caracteres de origen básico como de ejecución básica tendrán los siguientes miembros:
[...]
los 10 dígitos decimales
0 1 2 3 4 5 6 7 8 9
[...]
Tanto en los conjuntos de caracteres básicos de origen como de ejecución, el valor de cada carácter después de 0 en la lista anterior de dígitos decimales será uno mayor que el valor del anterior.
Tanto ASCII como EBCDIC, y los conjuntos de caracteres derivados de ellos, satisfacen este requisito, por lo que el estándar C fue capaz de imponerlo. Tenga en cuenta que las letras no son contiguas en EBCDIC, y C no las requiere.
No hay función de biblioteca para hacer un solo char
, primero necesitaría construir una cadena:
int digit_to_int(char d)
{
char str[2];
str[0] = d;
str[1] = ''/0'';
return (int) strtol(str, NULL, 10);
}
También puede usar la función atoi()
para realizar la conversión, una vez que tenga una cadena, pero strtol()
es mejor y más seguro.
Como comentaron los comentaristas, es extremadamente exagerado llamar a una función para hacer esta conversión; su enfoque inicial para restar ''0'' es la forma correcta de hacerlo. Solo quería mostrar cómo se usaría el enfoque estándar recomendado para convertir un número como una cadena a un número "verdadero", aquí.
Sí. Esto es seguro siempre que use caracteres ascii estándar, como lo es en este ejemplo.
Simplemente puede usar la función atol()
:
#include <stdio.h>
#include <stdlib.h>
int main()
{
const char *c = "5";
int d = atol(c);
printf("%d/n", d);
}
int i = c - ''0'';
Debe tener en cuenta que esto no realiza ninguna validación contra el personaje; por ejemplo, si el carácter era ''a'', entonces obtendría 91 - 48 = 49. Especialmente si está tratando con la entrada del usuario o de la red, probablemente debería realice la validación para evitar el mal comportamiento en su programa. Solo revisa el rango:
if (''0'' <= c && c <= ''9'') {
i = c - ''0'';
} else {
/* handle error */
}
Tenga en cuenta que si desea que su conversión maneje dígitos hexadecimales, puede verificar el rango y realizar el cálculo apropiado.
if (''0'' <= c && c <= ''9'') {
i = c - ''0'';
} else if (''a'' <= c && c <= ''f'') {
i = 10 + c - ''a'';
} else if (''A'' <= c && c <= ''F'') {
i = 10 + c - ''A'';
} else {
/* handle error */
}
Eso convertirá un único carácter hexadecimal, independiente en mayúscula o minúscula, en un número entero.