2010-09-02 19 views
6

Ich habe das folgende Programm:Warum druckt dieses C-Programm seltsame Zeichen in der Ausgabe?

#include <stdio.h> 

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

Egal, was ich gebe ich bekommen:

Read 

Warum ist das passiert und was ist das seltsame Zeichen, die ich sehe?

Stackoverflow druckt das seltsame Zeichen nicht. Sie können es hier sehen: http://ideone.com/EfZHr

+1

Wenn Sie gcc verwendet haben, stellen Sie sicher, dass Sie das Flag -Wall gesetzt haben. Unter den vielen häufigen Problemen, die es berichtet, ist dieser. – JeremyP

Antwort

18

Sie müssen Klammern setzen wie:

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

Precedence von != ist größer als die der =

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

ist die gleiche wie:

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

die liest ein Char vergleicht es mit Newline und dann weist das Ergebnis des Vergleichs zu ch. Nun das Ergebnis des Vergleichs ist 0 (wenn Newline eingegeben) oder 1 (wenn nichts anderes angegeben ist)

Die seltsamen Zeichen sind Sie zu sehen sind die control char mit Wert 1, gibt es keine druckbaren Zeichen für ASCII 1, so Ich denke, es ist die Shell, die das komische Zeichen mit dem Wert 0001 darin druckt.

Sie können es bestätigen, indem Sie Ihre Programmausgabe zu Oktal-Dump kochend (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, wenn sie mit -Wall verwendet warnt Sie, wie:

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

Gleiche Nachschlage-Referenz: D –

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

dieses Schreiben wird dazu führen, unerwartetes Verhalten in Abhängigkeit von den Sprachen operator precedence. In C = wird nach != ausgewertet, so dass ch wahr oder falsch sein wird. Versuchen:

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

Haben Sie keine saubereren Wörter, die kläglich versagen? –

+0

Ich tatsächlich - weiß nicht, warum ich diesen Wortlaut gestern gewählt habe, aber änderte es. –

2

C (und C++) interpretieren die while-Schleife als:

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

So ch erhält den Wert 1 (für true), die eine nicht druckbare Zeichen ist. Sie sollten explizite Klammern verwenden, um die Rangfolge zu beheben:

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

C, nicht C++ Kumpel. – Puppy

+0

Ah, tatsächlich. Aber das gilt für beide :) – bdonlan