Question

Quelle est la différence entre Atol () & strtol ()?

Selon leurs pages de manuel, ils semblent avoir le même effet, ainsi que les arguments correspondants:

long atol(const char *nptr);

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

Dans un cas généralisé, quand je ne veux pas utiliser l'argument base (je viens de nombres décimaux), quelle fonction dois-je utiliser?

Était-ce utile?

La solution

strtol vous offre une plus grande flexibilité, car il peut réellement vous dire si toute la chaîne a été convertie en un nombre entier ou non. atol, lorsqu'il est incapable de convertir la chaîne à un certain nombre (comme dans atol("help")), renvoie 0, ce qui est impossible à distinguer 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;
}

Sorties:

Got from help: 0, from zero: 0

strtol précisera, en utilisant son argument endptr, où la conversion a échoué.

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;
}

Sorties:

Conversion error, non-convertible part: help

Par conséquent, pour toute programmation sérieuse, je recommande vivement l'utilisation strtol. Il est un peu plus compliqué à utiliser, mais cela a une bonne raison, comme je l'ai expliqué ci-dessus.

atol peut convenir que pour les cas simples et contrôlés.

Autres conseils

fonctionnalité atol est un sous-ensemble de fonctionnalités de strtol, sauf que atol vous fournit pas de capacités de gestion des erreurs utilisables. Le problème le plus important avec des fonctions de ato... est qu'elles conduisent à un comportement non défini en cas de débordement. Remarque: ce n'est pas seulement un manque de informationel en cas d'erreur, c'est un comportement non défini , à savoir généralement une erreur irrécupérable

.

Cela signifie que la fonction atol (ainsi que toutes les autres fonctions de ato..) est à peu près inutile à des fins pratiques graves. Ce fut une erreur de conception et sa place est sur le parc à ferrailles de l'histoire C. Vous devez utiliser les fonctions du groupe strto... pour effectuer les conversions. Ils ont été introduits, entre autres, pour corriger les problèmes inhérents aux fonctions du groupe ato....

D'après la page de manuel atoi, il a été désapprouvée par 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.

Dans le nouveau code, je serais toujours utiliser strtol. Il a la gestion des erreurs et l'argument endptr vous permet de voir ce qui a été utilisé une partie de la chaîne.

Le C99 états standards sur les fonctions de ato*:

  

A l'exception du comportement en cas d'erreur, ils équivalent à

     

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

atol(str) est équivalent à

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

Utilisez strtol si vous voulez que le pointeur de fin (pour vérifier s'il y a plus de caractères à lire ou si, en fait, vous avez lu du tout) ou une base autre que 10. Dans le cas contraire, Atol est très bien.

Si ma mémoire est bonne, strtol() a l'avantage de mettre (en option) endptr au point au premier caractère qui ne pouvait pas être converti. Si NULL, il est ignoré. De cette façon, si vous traitez une chaîne contenant des chiffres et des caractères mélangés, vous pouvez continuer.

par ex.,

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 page de manuel de strtol donne ce qui suit:

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).

Le code vérifie pour les erreurs suivantes gamme. (Modifié le code d'Eli un peu)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top