2010-09-02 50 views
6

Tôi đã chương trình sau đây:Tại sao chương trình C này in các ký tự lạ trong đầu ra?

#include <stdio.h> 

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

Không có vấn đề gì tôi nhập tôi nhận được:

Read 

Tại sao điều này xảy ra và những gì là char lạ mà tôi nhìn thấy?

Stackoverflow không in char lạ. Bạn có thể nhìn thấy nó ở đây: http://ideone.com/EfZHr

+1

Nếu bạn đang sử dụng gcc, hãy đảm bảo bạn đã đặt cờ -Wall. Trong số rất nhiều vấn đề thường gặp, báo cáo là vấn đề này. – JeremyP

Trả lời

18

Bạn cần phải đặt dấu ngoặc đơn như:

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

Precedence của != là lớn hơn so với =

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

là giống như:

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

đọc lần so sánh chữ cái nó với newline và sau đó gán kết quả so sánh với ch. Bây giờ kết quả so sánh là 0 (khi xuống dòng được nhập) hoặc 1 (khi bất cứ điều gì khác được nhập)

Các char lạ bạn đang nhìn thấy là control char với giá trị 1, không có biểu tượng in cho ASCII 1, vì vậy Tôi đoán vỏ của nó in char lạ với giá trị 0001 trong đó.

Bạn có thể xác nhận nó bằng đường ống đầu ra chương trình của bạn để bãi bát phân (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 khi được sử dụng với -Wall cảnh báo bạn như:

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

Tham khảo tra cứu tương tự ưu tiên: D –

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

Viết này sẽ gây ra hành vi không mong muốn tùy thuộc vào ngôn ngữ operator precedence. Trong C = được đánh giá sau != vì vậy ch sẽ là đúng hoặc sai. Hãy thử:

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

Bạn không có bất kỳ từ nào rõ ràng hơn có nghĩa là thất bại không? –

+0

Tôi làm trong thực tế - không biết tại sao tôi đã chọn từ ngữ ngày hôm qua, nhưng đã thay đổi nó. –

2

C (C++) giải thích vòng lặp while như sau:

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

Vì vậy ch được giá trị 1 (cho đúng), mà là một nhân vật chưa in ra. Bạn nên sử dụng dấu ngoặc đơn rõ ràng để khắc phục quyền ưu tiên:

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

C, không phải là bạn C++. – Puppy

+0

Ah, thật vậy. Nhưng điều này áp dụng cho cả hai :) – bdonlan

Các vấn đề liên quan