atoi()
convierte una representación de cadena de un número entero en su valor. No convertirá caracteres arbitrarios en su valor decimal. Por ejemplo:
int main(void)
{
const char *string="12345";
printf("The value of %s is %d\n", string, atoi(string));
return 0;
}
No hay nada en la biblioteca estándar de C que convertirá "A" a 65 o "Z" a 90, que había necesidad de escribir que usted mismo, específicamente por cualquier juego de caracteres que está esperando como entrada.
Ahora que ya sabe lo que hace atoi()
, favor no lo use para hacer frente a la entrada numérica en todo lo que ocurra. Realmente deberías lidiar con los aportes que no son lo que esperas. Hmm, ¿qué sucede cuando ingreso 65 en lugar de A? A los maestros les encanta romper cosas.
atoi()
no hace ningún error en la comprobación de ningún tipo, lo que hace que todo lo que dependa de él para convertir una entrada arbitraria sea frágil, como mucho. En su lugar, utilice strtol()
(ejemplo centrada en POSIX):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
static const char *input ="123abc";
char *garbage = NULL;
long value = 0;
errno = 0;
value = strtol(input, &garbage, 0);
switch (errno) {
case ERANGE:
printf("The data could not be represented.\n");
return 1;
// host-specific (GNU/Linux in my case)
case EINVAL:
printf("Unsupported base/radix.\n");
return 1;
}
printf("The value is %ld, leftover garbage in the string is %s\n",
// Again, host-specific, avoid trying to print NULL.
value, garbage == NULL ? "N/A" : garbage);
return 0;
}
cuando es ejecutado, esto da:
El valor es 123, la basura sobrante en la cadena es abc
Si no me importa guardar/examinar la basura, puede establecer el segundo argumento en NULL
. No es necesario que free(garbage)
. También tenga en cuenta que si pasa 0 como tercer argumento, se supone que la entrada es el valor deseado de una representación decimal, hexadecimal o octal. Si necesita una raíz de 10, use 10 - fallará si la entrada no es la esperada.
También verificaría el valor de retorno para el valor máximo y mínimo que puede manejar un long int
. Sin embargo, si se devuelve alguno para indicar un error, se establece errno
. Un ejercicio para el lector es cambiar *input
de 123abc
a abc123
.
Es importante comprobar la devolución, ya que su ejemplo muestra lo que sucede si no lo hace. AbcDeFg no es una representación de cadena de un entero, y debe tratar eso en su función.
Para su aplicación, el consejo más básico que puedo dar que sería una serie de interruptores, algo así como:
// signed, since a return value of 0 is acceptable (NULL), -1
// means failure
int ascii_to_ascii_val(const char *in)
{
switch(in) {
// 64 other cases before 'A'
case 'A':
return 65;
// keep going from here
default:
return -1; // failure
}
.. entonces que basta con ejecutar en un bucle.
O rellene previamente un diccionario que una función de búsqueda podría abarcar (mejor). No necesitaría hashes, solo un almacén de claves -> value, ya que sabe lo que va a contener de antemano, donde los caracteres ASCII estándar son claves, y sus identificadores correspondientes son valores.
Pegue el código real que se compila. –
@Marcelo ¿Eso realmente importa en este caso? –
Tal vez, tal vez no. Pero, ¿es realmente tan difícil, dado que OP ya ha visto el resultado de ejecutar el programa? –