atoi vs atol vs strtol vs strtoul vs sscanf

Estoy tratando de averiguar a partir de una línea de comando que se está analizando, qué función sería la mejor para convertir un número decimal, hexadecimal u octal en un int el mejor, sin conocer la entrada de antemano.

El objective entonces es usar una sola función que reconozca los diferentes tipos de entradas y asignarla a su valor entero ( int ) que luego se puede usar para:

 ./a.out 23 0xC4 070 

podría imprimir

 23 196 /*hexadecimal*/ 56 /*octal*/ 

El único problema que puedo ver es el análisis para encontrar la diferencia entre un entero decimal y un octal.

Pregunta de lado, ¿es estable para convertir la cadena en un entero para usar?

¿Qué función sería la mejor para convertir un número decimal, hexadecimal u octal en un int el mejor (?)

Para convertir dicho texto a int , recomiendo long strtol(const char *nptr, char **endptr, int base); con pruebas adicionales al convertir a int , si es necesario.

Utilice 0 como base para evaluar los caracteres iniciales en la conversión de dirección como base 10, 16 u 8. @Mike Holt

 0x or 0X followed by hex digits--> hexadecimal 0 --> octal else --> decimal 

Código de muestra

 #include  #include  #include  int mystrtoi(const char *str) { char *endptr; errno = 0; // v--- determine conversion base long long_var = strtol(str, &endptr, 0); // out of range , extra junk at end, no conversion at all if (errno == ERANGE || *endptr != '\0' || str == endptr) { Handle_Error(); } // Needed when `int` and `long` have different ranges #if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX if (long_var < INT_MIN || long_var > INT_MAX) { errno = ERANGE; Handle_Error(); } #endif return (int) long_var; } 

atoi vs atol vs strtol vs strtoul vs sscanf

atoi()
Pro: Simple.
Pro: Convertir a un int .
Pro: En la biblioteca estándar de C.
Pro: rápido.
Con: No hay manejo de errores.
Con: Manejar ni hexadecimal ni octal.

atol()
Pro: Simple.
Pro: En la biblioteca estándar de C.
Pro: rápido.
Con: Convierte a un long , no int que puede diferir en tamaño.
Con: No hay manejo de errores.
Con: Manejar ni hexadecimal ni octal.

strtol()
Pro: Simple.
Pro: En la biblioteca estándar de C.
Pro: Buen manejo de errores.
Pro: rápido.
Con: Convertir a un long , no int que puede diferir en tamaño.

strtoul()
Pro: Simple.
Pro: En la biblioteca estándar de C.
Pro: Buen manejo de errores.
Pro: rápido.
—: Parece que no se quejan de los números negativos.
Con: Convierte a un unsigned long , no int que puede diferir en tamaño.

sscanf(..., "%i", ...)
Pro: En la biblioteca estándar de C.
Pro: Convierte a int .
—: la complejidad del medio de la carretera.
Con: Lento.
Con: OK manejo de errores (desbordamiento no está definido).

Todos sufren / se benefician de la configuración locale . §7.22.1.4 6 “En otros lugares que no sean la configuración regional” C “, se pueden aceptar formularios de secuencia de sujeto específicos de configuración regional adicionales”


Créditos adicionales:
@Jonathan Leffler : prueba de errno contra ERANGE , atoi() solo decimal, discusión acerca de la preocupación de multihilo de errno .
Tema @Marian Speed.
@Kevin Biblioteca inclusiva.


Para convertir caracteres short , signed char , etc., considere strto_subrange() .

Solo es sensato considerar strtol() y strtoul() (o strtoll() o strtoull() de , o quizás strtoimax() o strtoumax() de ) si te importa el error condiciones Si no le importan las condiciones de error en el desbordamiento, puede usar cualquiera de ellas. Ni atoi() ni atol() ni sscanf() le dan control si los valores se desbordan. Además, ni atoi() ni atol() brindan soporte para entradas hexadecimales u octales (por lo que en realidad no puede usarlas para satisfacer sus requisitos).

Tenga en cuenta que llamar a las funciones strtoX() no es del todo trivial. errno establecer errno en 0 antes de llamarlos, pasar un puntero para obtener la ubicación final y analizar cuidadosamente para saber qué sucedió. Recuerde, todos los valores de retorno posibles de estas funciones son salidas válidas, pero algunos de ellos también pueden indicar entradas no válidas, y errno y el puntero final le ayudan a distinguir entre todas ellas.

Si necesita convertir a int después de leer el valor usando, digamos, strtoll() , puede verificar el rango del valor devuelto (almacenado en un long long ) contra el rango definido en para int : INT_MIN y INT_MAX .

Para más detalles, vea mi respuesta en: Uso correcto de strtol() .

Tenga en cuenta que ninguna de estas funciones le indica qué conversión se utilizó. Tendrás que analizar la cuerda tú mismo. Nota extravagante: ¿sabía que no hay un decimal 0 en la fuente C? cuando escribes 0 , estás escribiendo una constante octal (porque su primer dígito es un 0 ). No hay consecuencias prácticas para esta pieza de trivia.