2010-09-02 2 views
6

J'ai le programme suivant:Pourquoi ce programme C imprime-t-il des caractères étranges dans la sortie?

#include <stdio.h> 

int main() 
{ 
     int ch; 
     while(ch = getchar() != '\n') { 
       printf("Read %c\n",ch); 
     } 
     return 0; 
} 

Peu importe ce que j'entre je reçois:

Read 

Pourquoi est-ce qui se passe et ce qui est que l'omble bizarre que je vois?

Stackoverflow n'imprime pas le caractère bizarre. Vous pouvez le voir ici: http://ideone.com/EfZHr

+1

Si vous utilisiez gcc, assurez-vous que l'indicateur -Wall est défini. Parmi les nombreux problèmes communs, il est celui-ci. – JeremyP

Répondre

18

Vous devez placer entre parenthèses comme:

while((ch = getchar()) != '\n') 

Precedence de != est supérieure à celle de =

while(ch = getchar() != '\n') 

est identique:

while(ch = (getchar() != '\n')) 

qui lit un caractère compare avec newline, puis assigne le résultat de la comparaison à ch. Maintenant, le résultat de la comparaison est 0 (quand est entré saut de ligne) ou 1 (quand tout le reste est entré)

CHAR bizarre que vous voyez est la control char avec une valeur 1, il n'y a pas de symbole imprimable pour ASCII 1, donc Je suppose que c'est le shell qui imprime le char étrange avec la valeur 0001 dedans.

Vous pouvez le confirmer en redirigeant votre sortie de programme à décharge octal (od):

$ echo 'a' | ./a.out | od -bc   # user entered 'a' 
0000000 122 145 141 144 040 001 012 
      R e a d  001 \n 
here you go ----------------^ 


$ echo '\n' | ./a.out | od -bc  # user entered '\n' 
0000000 

GCC lorsqu'il est utilisé avec -Wall vous met en garde contre comme:

warning: suggest parentheses around assignment used as truth value 
+1

Même référence de référence de précédence: D –

1
ch = getchar() != '\n' 

La rédaction de ce causera comportement inattendu en fonction des langues operator precedence. Dans C = est évalué après != alors ch sera vrai ou faux. Essayez:

(ch = getchar()) != '\n' 
+1

N'avez-vous pas des mots plus propres qui signifient échouer misérablement? –

+0

Je fais en fait - je ne sais pas pourquoi j'ai choisi cette formulation hier, mais l'ai changé. –

2

C (et C++) interpréter la boucle while que:

while(ch = (getchar() != '\n')) { 

Alors ch obtient la valeur 1 (pour vrai), ce qui est un caractère non imprimable. Vous devez utiliser une parenthèse explicite pour corriger la priorité:

while((ch = getchar()) != '\n') { 
+3

C, pas le copain C++. – Puppy

+0

Ah, en effet. Mais cela vaut pour les deux :) – bdonlan

Questions connexes