strtoul - strtol en c++
¿Cuál es el equivalente de atoi o strtoul para uint32_t y otros tipos de stdint? (2)
Estoy buscando las funciones estándar para convertir una cadena en un entero stdint.h , como
int i = atoi("123");
unsigned long ul = strtoul("123", NULL, 10);
uint32_t n = mysteryfunction("123"); // <-- ???
Dado que su pregunta se refiere a enteros unsigned
la verificación de desbordamiento es simple. Con una pequeña función de ayuda
inline
unsigned long long
strtoullMax(const char *nptr,
char **endptr,
int base,
unsigned long long maxval) {
unsigned long long ret = strtoll(nptr, endptr, base);
if (ret > maxval) {
ret = maxval;
errrno = ERANGE;
} else {
if (ret == ULLONG_MAX && errno == ERANGE)
ret = maxval;
}
return ret;
}
fácilmente puede definir macros que funcionen para cualquier tipo de interés
#define strtou32(NPTR, ENDPTR, BASE) /
strtoullMax(NPTR, ENDPTR, BASE, (uint32_t)-1)
#define strtou32f(NPTR, ENDPTR, BASE) /
strtoullMax(NPTR, ENDPTR, BASE, (uint_fast32_t)-1)
#define strtou32l(NPTR, ENDPTR, BASE) /
strtoullMax(NPTR, ENDPTR, BASE, (uint_least32_t)-1)
Hay dos opciones generales: strto[iu]max
seguido de una comprobación para ver si el valor se ajusta en el tipo más pequeño, o cambiar a sscanf
. El estándar C define una familia completa de macros en <inttypes.h>
que se expanden al especificador de conversión apropiado para los tipos <stdint.h>
. Ejemplo para uint32_t
:
#include <inttypes.h>
#include <stdio.h>
int main()
{
uint32_t n;
sscanf("123", "%"SCNu32, &n);
printf("%"PRIu32"/n", n);
return 0;
}
(En el caso de uint32_t
, strtoul
+ check overflow también funcionaría para uint32_t
porque unsigned long
tiene al menos 32 bits de ancho. No funcionaría de manera confiable para uint_least32_t
, uint_fast32_t
, uint64_t
, etc.)
Editar : como dice Jens Gustedt a continuación, esto no ofrece la flexibilidad total de strtoul
en cuanto a que no se puede especificar la base. Sin embargo, aún es posible obtener la base 8 y la base 16 con SCNo32
y SCNx32
, respectivamente.