Skip to content
Tiantan
Articles

Stockage du caractère EOF (End of File) dans un type de caractère

On février 18, 2021 by admin

Jai lu dans le langage de programmation C de Dennis Ritchie livre que int doit être utilisé pour quune variable contienne EOF – pour la rendre suffisamment grande pour quelle puisse contenir la valeur EOF – pas char. Mais le code suivant fonctionne très bien:

#include<stdio.h> main() { char c; c=getchar(); while(c!=EOF) { putchar(c); c=getchar(); } } 

Quand il y a nest plus une entrée, getchar renvoie EOF. Et dans le programme ci-dessus, la variable c, de type char, est capable de la contenir avec succès.

Pourquoi cela fonctionne-t-il? Comme expliqué dans le livre ci-dessus, le code ne devrait pas fonctionner.

Commentaires

  • Il ny a pas de caractère EOF.
  • Ce code est susceptible déchouer si vous lisez un caractère avec la valeur 0xff. Stockage du résultat de getchar() dans un int résout ce problème. Votre question est essentiellement la même que la question 12.1 de la FAQ comp.lang.c , qui est une excellente ressource. (De plus, main() devrait être int main(void), et cela ne ferait pas ' dajouter un return 0; avant la clôture }.)
  • @delnan: larticle lié nest pas ' t tout à fait raison sur la façon dont Unix traite control-D. Cela ne ' t ferme pas le flux dentrée; cela provoque simplement le retour immédiat de tout fread () bloquant sur la console avec toutes les données non encore lues. De nombreux programmes interprètent un retour de zéro octet de fread () comme indiquant EOF, mais le fichier restera en fait ouvert et pourra fournir plus dentrée.

Answer

Votre code semble fonctionner, car les conversions de types implicites se produisent accidentellement pour faire la bonne chose.

getchar() renvoie un int avec une valeur qui correspond à la plage de unsigned char ou est EOF ( qui doit être négatif, généralement -1). Notez que EOF lui-même nest pas un caractère, mais un signal quil ny a plus de caractères disponibles.

Lors du stockage du résultat de getchar() dans c, il y a deux possibilités. Soit le type char peut représenter la valeur, auquel cas cest la valeur de c. Ou le type char ne peut pas représenter la valeur. Dans ce cas, ce qui va se passer nest pas défini. Les processeurs Intel coupent simplement les bits hauts qui ne correspondent pas au nouveau type (réduisant effectivement la valeur modulo 256 pour char), mais vous ne devriez pas vous y fier.

Létape suivante consiste à comparer c avec EOF. Comme EOF est un int, c sera également converti en int, en préservant la valeur stockée dans c. Si c pouvait stocker la valeur de EOF, alors la comparaison réussira , mais si c ne pouvait pas stocker la valeur, alors la comparaison échouera, car il y a eu une perte irrécupérable dinformations lors de la conversion de EOF pour taper char.

Il semble que votre compilateur ait choisi de créer le type char signé et la valeur de EOF petite assez pour tenir dans char. Si char nétait pas signé (ou si vous aviez utilisé unsigned char), votre test aurait échoué, car unsigned char ne peut « t contenir la valeur de EOF.


Notez également quil y a un deuxième problème avec votre code. Comme EOF nest pas un caractère lui-même, mais vous le forcez dans un type char, il y a très probablement un caractère là-bas qui est mal interprété comme étant EOF et pour la moitié des caractères possibles, il est indéfini sils seront traités correctement.

Commentaires

  • Coercition pour saisir des valeurs de char en dehors de la plage CHAR_MIN .. CHAR_MAX sera nécessaire pour donner soit une valeur définie par limplémentation, renvoie un modèle de bits que limplémentation définit comme une représentation dinterruption ou déclenche un signal défini par limplémentation. Dans la plupart des cas, les implémentations doivent faire beaucoup de travail supplémentaire pour faire autre chose que deux ' réduction du complément s.Si les membres du Comité des normes souscrivaient à lidée que les compilateurs devraient être encouragés à mettre en œuvre des comportements cohérents avec celui de la plupart des autres compilateurs en labsence de raisons de faire autrement …
  • … la coercition comme étant fiable (pour ne pas dire que le code ne devrait pas ' t documenter ses intentions, mais que (signed char)x devrait être considéré comme plus clair et tout aussi sûr comme ((unsigned char)x ^ CHAR_MAX+1))-(CHAR_MAX+1).) En létat, je ne vois ' aucune probabilité que les compilateurs implémentent tout autre comportement conforme à aujourdhui '; le seul danger serait que la norme puisse être modifiée pour briser le comportement dans lintérêt supposé de " optimisation ".
  • @supercat: Le standard est écrit de telle sorte quaucun compilateur nait à produire du code dont le comportement nest pas naturellement pris en charge par le processeur quil cible. La plupart des comportements non définis sont présents car (au moment de la rédaction de la norme) tous les processeurs ne se comportaient pas de manière cohérente. Les compilateurs devenant plus matures, les rédacteurs de compilateurs ont commencé à profiter du comportement non défini pour faire des optimisations plus agressives.
  • Historiquement, lintention du Standard était principalement celle que vous décrivez, bien que le Standard décrit certains comportements dans suffisamment de détails pour exiger que les compilateurs de certaines plates-formes courantes génèrent plus de code que ce qui serait requis dans une spécification plus souple. La contrainte de type dans int i=129; signed char c=i; est lun de ces comportements. Relativement peu de processeurs ont une instruction qui rendrait c égal i quand il ' la plage de -127 à +127 et donnerait tout mappage cohérent des autres valeurs de i aux valeurs de la plage de -128 à +127 qui différaient de deux ' réduction du complément s, ou …
  • … augmenterait systématiquement un signal dans de tels cas. Étant donné que la norme exige que les implémentations produisent un mappage cohérent ou augmentent systématiquement un signal, les seules plates-formes où la norme laisserait de la place pour autre chose que deux ' réduction du complément s seraient des choses comme les DSP avec du matériel arithmétique saturant. En ce qui concerne la base historique du comportement indéfini, je dirais que le problème ' nest pas uniquement lié aux plates-formes matérielles. Même sur une plate-forme où le débordement se comporterait de manière très cohérente, il peut être utile davoir un compilateur le piéger …

Written by admin

Laisser un commentaire Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Articles récents

  • En utilisant un balun avec un dipôle résonnant
  • Quelle est la différence entre “ ne peut pas ” et “ ne peut pas ”? [dupliquer]
  • “ Profondément apprécié ” ou “ très apprécié ”
  • Que signifie ' idées abstraites '? [fermé]
  • Pourquoi ' t je ne devrais pas utiliser le cryptage ECB?

Archives

  • février 2021
  • janvier 2021
  • décembre 2020
  • novembre 2020
  • Deutsch
  • Nederlands
  • Svenska
  • Norsk
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語
  • 한국어

Copyright Tiantan 2021 | Theme by Theme in Progress | Proudly powered by WordPress

Back to top