strtoul c type-conversion c99 stdint

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.