Utiliser scanf dans une boucle while
Probablement extrêmement simple de répondre à cette question extrêmement simple:
Je suis en train de lire "C Primer Plus" en Pratta et il continue à l'aide de l'exemple
while (scanf("%d", &num) == 1)...
Est l' == 1-elle vraiment nécessaire? Il semble que l'on pourrait simplement écrire:
while (scanf("%d", &num))
Il semble que le test d'égalité est inutile car scanf renvoie le nombre d'objets lus et 1 permettrait de faire la boucle while true. Est la raison pour laquelle assurez-vous que le nombre d'éléments de la lecture est de 1 ou est-ce totalement superflu?
source d'informationauteur Tyler Brock
Vous devez vous connecter pour publier un commentaire.
En C, 0 est évalué à false et que tout le reste de vrai. Ainsi, si scanf retourné EOF, qui est une valeur négative, la boucle est évaluée à true, ce qui n'est pas ce que vous voulez.
Depuis
scanf
renvoie la valeur EOF (-1) à la fin du fichier, la boucle comme l'écrit est correct. Il fonctionne aussi longtemps que l'entrée contient le texte qui correspond à%d
et s'arrête à la première non-match ou la fin du fichier.Il aurait été plus clair d'un coup d'oeil si
scanf
attendaient plus d'une entrée....permettrait de sortir de la boucle quand la première fois qu'il a été incapable de répondre à deux valeurs, soit en raison de la fin de fichier à la fin du fichier (
scanf
retourne EOF (-1)) ou sur l'entrée correspondant erreur (par exemple, l'entréexyzzy 42
ne correspond pas%d %d
doncscanf
s'arrête sur la première défaillance et renvoie 0 sans écriture soitx
ouy
) lorsqu'il renvoie à une valeur inférieure à 2.Bien sûr,
scanf
est pas votre ami lors de l'analyse réelle de l'entrée de l'homme normal. Il ya de nombreux pièges dans sa manière de traiter les cas d'erreur.Edit: correction d'une erreur:
scanf
retourneEOF
sur la fin du fichier, ou un entier non négatif de compter le nombre de variables qu'il a réussi à mettre.Le point clé est que depuis toute valeur non nulle est
TRUE
en C, à défaut de tester la valeur de retour correctement dans une boucle comme cela peut facilement conduire à un comportement inattendu. En particulier,while(scanf(...))
est une boucle infinie, sauf si elle rencontre de saisir le texte qui ne peut pas être converti en fonction de son format.Et je ne peut pas trop insister sur le fait que
scanf
est pas votre ami. Une combinaison defgets
etsscanf
peut être suffisant pour une analyse simple, mais même alors, il est facilement submergés par les cas limites et les erreurs.Vous avez compris le code C correctement.
Parfois, la raison pour le test le nombre d'éléments de lecture, c'est que quelqu'un veut assurez-vous que tous les articles ont été lus au lieu de scanf arrêter de fumer dès le début quand il l'entrée ne correspond pas au type attendu. Dans ce cas particulier, il n'avait pas d'importance.
Généralement scanf est un mauvais choix pour les fonctions, car il ne répond pas aux besoins de l'interaction d'un utilisateur humain. Habituellement une combinaison de fgets et sscanf d'obtenir de meilleurs résultats. Dans ce cas particulier, il n'avait pas d'importance.
Si les chapitres suivants expliquent pourquoi certains types de pratiques de codage sont mieux que cet exemple trivial, bon. Mais si non, vous devriez vider le livre que vous êtes en train de lire.
D'autre part, votre mandataire code n'est pas exactement un substitut. Si scanf retourne -1, alors votre alors que la boucle s'exécute.
Bien que vous avez raison, il n'est pas strictement nécessaire, certaines personnes préfèrent pour plusieurs raisons.
Tout d'abord, en comparant à 1, il devient explicite d'une valeur booléenne (true ou false). Sans le titre de comparaison, vous sont à l'essai sur un entier, qui est valide en C, mais pas plus tard langages (comme C#).
Deuxièmement, certaines personnes de lire le deuxième version en termes de temps([fonction]), au lieu de tout([valeur]), et être momentanément confus par le test d'une fonction, quand ce qui est signifie clairement est de tester la valeur de retour.
Cela peut être une affaire de préférence personnelle, et pour autant que je suis concerné, les deux sont valables.
On pourrait probablement écrire sans une comparaison explicite (voir le JRL de réponse), mais pourquoi? Je dirais que la comparaison, moins de conditions doivent être utilisées uniquement avec les valeurs qui ont explicitement boolean sémantique (comme un
isdigit()
appel, par exemple). Tout le reste doit utiliser une comparaison explicite. Dans ce cas (le résultat descanf
) la sémantique est pronouncedly non-booléenne, de sorte que la comparaison explicite est dans l'ordre.Aussi, la comparaison, on peut généralement omettre est normalement une comparaison avec zéro. Lorsque vous ressentez l'envie d'omettre la comparaison avec quelque chose d'autre (comme
1
dans ce cas), il vaut mieux réfléchir à deux fois et assurez-vous que vous savez ce que vous faites (voir le JRL de réponse encore une fois).Dans tous les cas, lorsque la comparaison peut les oublier et que vous l'omettez, la sémantique de la maladie reste la même. Il n'a absolument aucun impact sur l'efficacité de la résultante de code, si c'est quelque chose que vous êtes de se préoccuper.