Dans le langage de programmation C, une chaîne telle que "2147483649" déborde en tant qu'int puisque le plus grand int non signé est 2147483647. Lorsque je veux convertir des chaînes d'entiers en int s, comment puis-je vérifier ces cas de dépassement de capacité?

Je ne peux pas simplement vérifier si c'est >=-(2^32-1) et <= (2^32-1) puisque le processus de conversion de cette chaîne en int (par exemple atoi()) modifie déjà cette valeur. Existe-t-il un moyen simple au lieu de vérifier le nombre de chiffres de la chaîne avant la conversion et également chaque chiffre à la fois pour s'assurer qu'il est dans la plage de int s?

1
domoremath 26 janv. 2017 à 11:36

4 réponses

Meilleure réponse

L'utilisation de atoi() sur une valeur qui ne peut pas être représentée comme un entier appelle un comportement indéfini. C'est à dire. vous ne devez pas utiliser atoi().

À la place, vous pouvez utiliser strtol():

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

long val = strtol("2147483649", 0, 10);
if (val == LONG_MIN && errno == ERANGE) {
    …underflow…
} else if (val == LONG_MAX && errno == ERANGE) {
    …overflow…
}
3
kamikaze 26 janv. 2017 à 08:46

Si vous implémentez votre propre fonction atoi, vous pouvez vérifier le dépassement au fur et à mesure que vous accumulez le résultat:

int value = 0;
for-each digit-character in string
    int newValue = value + ( 10 * place * digit-character )
    if newValue < value then die("overflow detected")
    value = newValue
next
0
Dai 26 janv. 2017 à 08:40

Vous pouvez reconvertir l'entier résultant en chaîne et le comparer à la chaîne source. Bien que cela ne me paraisse pas élégant. :-)

5
D. Mika 26 janv. 2017 à 08:42

Utilisez strtol(). Cela vous donne un long, donc si sur votre plate-forme est plus grand qu'un int, vous pouvez vérifier qu'il n'y a pas de débordement. Et si le nombre dans la chaîne ne rentre même pas dans un long, la fonction renverra une valeur spéciale LONG_MIN ou LONG_MAX et définira errno.

0
John Zwinck 26 janv. 2017 à 08:39