web-dev-qa-db-fra.com

Équivalent d'atoi pour les entiers non signés

Je fais deux opérations impliquant atoi et je me demande comment je peux le faire avec des entiers non signés car atoi semble les convertir en signés provoquant un débordement d'entier enveloppant. Je veux travailler avec des entiers non signés 32 bits mais atoi me limite effectivement à 31 bits non signés.

 if (multiplication_is_safe(atoi(argv[1]),atoi(argv[3])))
    {
     printf("%s * %s = %u \n", argv[1], argv[3], atoi(argv[1]) * atoi(argv[3]));
      return 0;
    }  else
16
John

La réponse simple est d'utiliser à la place strtoul() .

La réponse la plus longue est que même si tout ce dont vous aviez besoin était des entiers 32 bits signés ou étaient satisfaits de 31 bits pour les non signés, la fonction atoi() ne convenait pas à ce que vous sembliez faire.

Comme vous l'avez déjà noté, la fonction atoi() convertit une chaîne en entier. Un entier signé normal. Cependant, ce que atoi() ne fait pas est la gestion des erreurs. Ce que la spécification de atoi() dit est " Si la valeur ne peut pas être représentée, le comportement n'est pas défini. "

La famille de fonctions strto * () spécifie clairement la façon dont les erreurs sont traitées, vous devez donc dans tous les cas remplacer atoi() par des appels à strtol() (convertir la chaîne en long), et dans ce cas, Dans la mesure où vous souhaitez gérer des entiers non signés, vous devez utiliser strtoul() (convertir la chaîne en unsigned long).

Notez également que si vous souhaitez gérer des nombres plus importants, il existe les fonctions strtoll() et strtoull(), pour convertir votre chaîne en un long long ou un long long non signé. (Et si vous voulez juste gérer les plus grandes valeurs intégrales possibles sans vous soucier de tout ce qui se trouve entre les deux, il y a strtoimax() et strtoumax(), qui renvoient des valeurs de type intmax_t ou uintmax_t respectivement.)

Documentation POSIX:

23

Selon votre plateforme, strtoul est probablement ce que vous voulez:

La fonction strtoul () convertit la partie initiale de la chaîne dans nptr en une valeur entière longue non signée selon la base donnée, qui doit être comprise entre 2 et 36 inclus, ou être la valeur spéciale 0.

2