7
votes

Comparaison de Char et EOF non signé

Lorsque le code suivant est compilé, il passe dans une boucle infinie:

abc.c:13:warning: comparison is always true due to limited range of data type


3 commentaires

essentiellement la même chose que fgetc n'identifie pas EOF . Je pense que nous avons ce type de question au moins une fois par semaine.


Voir aussi C-FAQ.com/stdio/getcharc.html


Duplicatural possible de Pourquoi La variable utilisée pour tenir la valeur de retour de GetChar de GetChart soit déclarée par int?


6 Réponses :


2
votes

Vous devez utiliser un int

fgetc () renvoie une INT spécifiquement afin qu'elle puisse indiquer la fin du fichier

Il fonctionne bien avec un caractère signé parce que EOF (-1) est dans la gamme, mais il se briserait si vous lisez dans une valeur de valeur supérieure à 127.

Utilisez un Int, jeté à un charret après avoir vérifié pour EOF


3 commentaires

Je sais que nous devrions être utilisés dans un code approprié, mais je veux savoir pourquoi non signé Char ne fonctionne pas mais non signé int fonctionne ...


Comment -1 est dans la gamme de non signé Int


Lisez sur les règles de promotion entier.



10
votes

La règle d'or pour écrire cette ligne est xxx pré>

ch code> devrait être int code> strong> .votre mignon Astuce de fabrication ch code> non signé échoue car EOF code> est une quantité INT signée. P>

OK, allons maintenant dans la profondeur ...... <. p>

étape 1: strong> p> xxx pré>

fgetc () code> retourne -1 code > (un int code>). Par les règles d'or de C ch code> obtient le dernier octet de bits qui est tout 1 code>'s. Et d'où la valeur 255 code>. Le modèle d'octet de ch code> après l'exécution de p> xxx pré>

serait ainsi p> xxx pré>

ÉTAPE 2: STRUT> P>

while ((ch = fgetc(stdin)) != EOF)


3 commentaires

La règle d'or est correspond toujours à vos parenthèses . Vous manquez un ) dans les deux exemples, il doit être tandis que ((ch = fgetc. (stdin))! = EOF) .


Je viens de faire votre réponse claire un peu plus agréable. Néanmoins, pourriez-vous s'il vous plaît élaborer sur ce que vous voulez exprimer ce modèle: ... = (255) 10 et ... = (-1) 10 ?


@alk Cette réponse a été écrite par "l'étudiant moi", d'où l'incohérence dans les notations. (255) 10 indique 255 dans la base 10



1
votes

Lorsque vous comparez un INT non signé avec un INT signé, il convertit le INT signé vers UNSIGED INT et les compare. Par conséquent, lorsque vous lisez le fichier avec un int 'CH' non signé, la lecture d'un EOF vous donne 2 ^ 32 + 1 (sur une machine d'intensité de 4 octets) et lorsque vous le comprenez avec EOF, il convertit EOF en non signé qui est également 2 ^ 32 + 1 et par conséquent, le programme s'arrête!

Si vous utilisez UNSIGED CHR CH, lorsque vous lisez le fichier, la lecture de l'EOF renvoie 2 ^ 32 + 1, et cela sera coulé sur un caractère non signé, ce qui tronque la valeur au premier Bits (sur un octet de charcuterie) et vous donne une sortie de 255. Vous comparez donc 255 et 2 ^ 32 + 1, provoquant une boucle infinie. P>

Le problème ici est tronquant avant de comparer.

Si vous utilisez P>

while((ch = fgetc(fp))!=(unsigned char)EOF)
    printf("%c",ch);


0 commentaires

7
votes

Il y a plusieurs conversions implicites. Ils ne sont pas vraiment pertinents pour l'avertissement spécifique, mais je les ai inclus dans cette réponse pour montrer ce que le compilateur fait vraiment avec cette expression.

  • CH Dans votre exemple est de type non signé Char.
  • EOF est garanti d'être de type INT (C99 7.19.1).

    de sorte que l'expression est équivalente à xxx

    Les règles de promotion entier en C convertiront implicitement le caractère non signé en int. : xxx

    puis les règles d'équilibrage (AKA les conversions arithmétiques habituelles ) en C convertiront implicitement l'intégration à l'INT non signé, car chaque opérande doit avoir Le même type: xxx

    sur votre compilateur EOO est probable -1: xxx

    qui, en supposant une CPU 32 bits , est identique à celui xxx

    un caractère ne peut jamais avoir une valeur aussi élevée, d'où l'avertissement.


0 commentaires

2
votes

J'ai aussi rencontré ce problème. Ma solution consiste à utiliser Feof ().

int flag;
unsigned char c;
while((flag = fgetc(fin)) != EOF) 
{ 
  //so, you are using flag to receive, but transfer the value to c later.
  c = flag;
  ... 
}


0 commentaires

0
votes

Un avertissement de peluche est produit avec ce type de mise en œuvre

comparer le type 'Char' avec EOF xxx

correction: xxx


0 commentaires