0
votes

Pourquoi scanf renvoie-t-il une valeur positive même lorsque l'entrée est plus grande que le type numérique donné?

Compte tenu du code suivant:

Number of receiving arguments successfully assigned.

pourquoi scanf retourne-t-il 1 lorsque l'utilisateur entre un nombre plus grand que INT_MAX ou même plus grand que LONG_MAX ?

De la documentation :

int x;
int r = scanf("%d", &x);

Pourquoi x est-il considéré comme attribué avec succès? Qu'est-ce que cela signifie exactement dans ce contexte? Lorsque l'utilisateur donne des nombres compris entre INT_MAX et LONG_MAX , x semble être la moitié inférieure du résultat. Je sais que scanf utilise strtol interne mais scanf pourrait déterminer que le type int est trop petit pour contenir le résultat. De plus, lors du passage d'un nombre géant, plus grand que LONG_MAX , la valeur de x est -1 et la valeur de retour est toujours 1 et je dois me fier à errno pour vérifier que quelque chose s'est mal passé ( errno == ERANGE ).

Que signifie «assigné avec succès» et pourquoi scanf retourne-t-il 1 étant donné qu'il pourrait si facilement dire que le résultat est, en fait, des ordures?

c

3 commentaires

Notez que scanf renverrait 1 même avec une entrée comme 123a .


"scanf pourrait déterminer que le type int est trop petit pour contenir le résultat." -> Oui c'est possible, mais la fonction n'est pas définie pour le faire. Maintenant, si vous étiez il y a environ 40 ans, les choses auraient pu être différentes. (Rappelez-vous que la mémoire coûte peut-être 10000 fois ce qu'elle fait aujourd'hui)


Vous devez écrire votre propre fonction de conversion


4 Réponses :


-2
votes

Rappelez-vous que scanf (et ses frères et sœurs) est une fonction variadique. Il est utile de dire à l'appelant combien d'arguments ont été attribués avec succès, où «avec succès» peut signifier moins que vous ne le pensez. Il est de la responsabilité de l'appelant de s'assurer que les arguments concordent.


0 commentaires

1
votes

pourquoi scanf retourne-t-il 1 lorsque l'utilisateur entre un nombre plus grand que INT_MAX ou même plus grand que LONG_MAX?

Il s'agit d' un comportement indéfini (UB) lorsque le texte d'entrée est converti en dehors de la plage int pour "%d" . C'est une faiblesse de spécification de scanf() .
Tout peut arriver.

Un code robuste sépare l'entrée de la conversion. Regardez fgets() et strtol() .


0 commentaires

1
votes

Malheureusement, vous ne pouvez pas vous fier à errno == ERANGE ou autre dans les programmes C portables.

fscanf n'est pas documenté avec autorité sur cppreference.com, mais dans la norme ISO C. Premièrement, la norme stipule que

  1. La fonction fscanf renvoie la valeur de la macro EOF si un échec d'entrée se produit avant la fin de la première conversion (le cas échéant). Sinon, la fonction renvoie le nombre d'éléments d'entrée affectés , qui peut être inférieur à celui prévu, voire zéro, en cas d'échec de la correspondance précoce.

C'est-à-dire nulle part qu'il ne contient le mot «réussi».

Au contraire, il dit:

[...] si le résultat de la conversion ne peut pas être représenté dans l'objet, le comportement n'est pas défini.

Ie malheureusement il n'y a aucune garantie de comportement dans ce cas. En particulier, la norme ne déclare jamais que le résultat serait le plus grand nombre, ou que errno contiendrait ERANGE ou toute autre chose du genre.


0 commentaires

0
votes

"scanf" est une fonction qui lit les données au format spécifié à partir d'une source de flux de chaînes donnée. Il permet au programmeur d'accepter les entrées du périphérique d'entrée standard (clavier) et de les stocker dans des variables.

«scanf» signifie «format de numérisation», car il analyse l'entrée des jetons valides et les analyse selon un format spécifié.

Lit un nombre réel que (par défaut) l'utilisateur a saisi dans la variable miles

  • Chaque variable doit être précédée de l'opérateur adresse-de (&).
  • Nous pouvons lire les valeurs dans plusieurs variables avec un seul scanf tant que nous avons des chaînes de format correspondantes pour chaque variable.

"scanf" accomplissant avec succès la fonction 'format de numérisation'. Ce n'est pas la fonction de "scanf" de vérifier la plage pour le type de données correspondant.


0 commentaires