2010-09-02 45 views
6

Sono il seguente programma:Perché questo programma in C stampa caratteri strani in uscita?

#include <stdio.h> 

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

Non importa quello che io entro ottengo:

Read 

Perché succede questo e che cosa è che strano char che vedo?

Stackoverflow non sta stampando il carattere strano. Potete vederlo qui: http://ideone.com/EfZHr

+1

Se si utilizza gcc, assicurarsi di disporre del set di flag di -Wall. Tra i molti problemi comuni che riporta è questo. – JeremyP

risposta

18

è necessario inserire le parentesi come:

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

Precedence di != è maggiore di quella di =

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

è lo stesso:

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

che legge un confronto di caratteri con newline e quindi assegna il risultato del confronto a ch. Ora il risultato del confronto è 0 (quando viene immesso nuova riga) o 1 (quando si entra qualsiasi altra cosa)

Il carattere strano che stai vedendo è la control char con valore di 1, non c'è nessun simbolo stampabile per ASCII 1, in modo da Immagino sia il guscio che stampa il carattere strano con il valore 0001 in esso.

È possibile confermare che convogliando l'output del programma a discarica ottale (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 quando viene utilizzato con -Wall si avverte come:

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

Stessa precedenza per la ricerca della precedenza: D –

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

Scrivere questo causerà comportamento imprevisto a seconda delle lingue operator precedence. In C = viene valutato dopo != quindi ch sarà vero o falso. Prova:

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

Non hai parole più pulite che significano fallire miseramente? –

+0

In effetti, non so perché ho scelto quella dicitura ieri, ma l'ho cambiata. –

2

C (e C++) interpretare il ciclo while come:

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

Così ch ottiene il valore 1 (per vero), che è un carattere non stampabile. È necessario utilizzare la parentesi esplicita per correggere la precedenza:

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

C, non amico di C++. – Puppy

+0

Ah, davvero. Ma questo vale per entrambi :) – bdonlan