atol () v / s. strtol ()

¿Cuál es la diferencia entre atol () y strtol ()?

De acuerdo con sus páginas man, parecen tener el mismo efecto, así como los argumentos coincidentes:

long atol(const char *nptr); long int strtol(const char *nptr, char **endptr, int base); 

En un caso generalizado, cuando no quiero usar el argumento base (solo tengo números decimales), ¿qué función debo usar?

    strtol proporciona más flexibilidad, ya que realmente puede decirle si toda la cadena se convirtió en un número entero o no. atol , cuando no se puede convertir la cadena a un número (como en atol("help") ), devuelve 0, que es indistinguible de atol("0") :

     int main() { int res_help = atol("help"); int res_zero = atol("0"); printf("Got from help: %d, from zero: %d\n", res_help, res_zero); return 0; } 

    Productos:

     Got from help: 0, from zero: 0 

    strtol especificará, utilizando su argumento endptr , donde falló la conversión.

     int main() { char* end; int res_help = strtol("help", &end, 10); if (!*end) printf("Converted successfully\n"); else printf("Conversion error, non-convertible part: %s", end); return 0; } 

    Productos:

     Conversion error, non-convertible part: help 

    Por lo tanto, para cualquier progtwigción seria, definitivamente recomiendo usar strtol . Es un poco más complicado de usar, pero esto tiene una buena razón, como expliqué anteriormente.

    atol puede ser adecuado solo para casos muy simples y controlados.

    atol funcionalidad atol es un subconjunto de la funcionalidad de strtol , excepto que atol proporciona capacidades de manejo de errores utilizables. El problema más destacado con las funciones ato... es que conducen a un comportamiento indefinido en caso de desbordamiento. Nota: esto no es solo una falta de retroalimentación informativa en caso de error, este es un comportamiento indefinido , es decir, generalmente es una falla irrecuperable.

    Esto significa que la función atol (así como todas las demás funciones ato.. ) es bastante inútil para propósitos prácticos serios. Fue un error de diseño y su lugar está en el depósito de chatarra de la historia de C. Debe usar funciones de strto... group para realizar las conversiones. Se les presentó, entre otras cosas, para corregir los problemas inherentes a las funciones de un ato... grupo.

    De acuerdo con la página man de atoi , strtol lo ha dejado de strtol .

     IMPLEMENTATION NOTES The atoi() and atoi_l() functions have been deprecated by strtol() and strtol_l() and should not be used in new code. 

    En el nuevo código, siempre usaría strtol . Tiene endptr errores y el argumento endptr permite ver qué parte de la cadena se utilizó.

    El estándar C99 establece acerca de las funciones ato* :

    Excepto por el comportamiento por error, equivalen a

    atoi: (int)strtol(nptr,(char **)NULL, 10)
    atol: strtol(nptr,(char **)NULL, 10)
    atoll: strtoll(nptr, (char **)NULL, 10)

    atol(str) es equivalente a

     strtol(str, (char **)NULL, 10); 

    Usa strtol si quieres el puntero final (para verificar si hay más caracteres para leer o si de hecho lo has leído) o una base distinta de 10. De lo contrario, atol está bien.

    Si la memoria se sirve, strtol() tiene el beneficio adicional de configurar el endptr (opcional) para que apunte al primer carácter que no se pudo convertir. Si es NULL , se ignora. De esa manera, si está procesando una cadena que contiene números y caracteres mezclados, puede continuar.

    p.ej,

     char buf[] = "213982 and the rest"; char *theRest; long int num = strtol(buf, &theRest, 10); printf("%ld\n", num); /* 213982 */ printf("%s\n", theRest); /* " and the rest" */ 

    La página man de strtol da lo siguiente:

     ERRORS EINVAL (not in C99) The given base contains an unsupported value. ERANGE The resulting value was out of range. The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned). 

    El siguiente código verifica los errores de rango. (Modificó el código de Eli un poco)

     #include  #include  #include  #include  int main() { errno = 0; char* end = 0; long res = strtol("83459299999999999K997", &end, 10); if(errno != 0) { printf("Conversion error, %s\n", strerror(errno)); } else if (*end) { printf("Converted partially: %i, non-convertible part: %s\n", res, end); } else { printf("Converted successfully: %i\n", res); } return 0; }