2012-08-14 19 views
7

Đây là mã của tôi. Tôi chạy nó trong ubuntu với thiết bị đầu cuối. khi tôi nhập (CtrlD) trong thiết bị đầu cuối, chương trình không dừng lại nhưng vẫn tiếp tục chờ đầu vào của tôi.ctrl-d không dừng lại trong khi vòng lặp (getchar()! = EOF)

Không phải là CtrlD bằng EOF trong unix?

Cảm ơn bạn.

#include<stdio.h> 

main() { 
    int d; 
    while(d=getchar()!=EOF) { 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
     printf("EOF:%d\n", EOF); 
    } 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
} 
+1

Đó không phải là đệ quy. Nó chỉ là một vòng lặp vô hạn cho đến khi bạn EOL đầu vào. Đệ quy = hàm gọi chính nó trực tiếp hoặc sau một số bước trung gian khác. –

+0

Biên dịch với gcc, nhấn '^ D' đã dừng vòng lặp cho tôi. –

+0

@JonLin Đơn giản chỉ cần nhập^D. Nó cũng làm việc cho tôi. Tuy nhiên, khi đầu vào là (a^D), vòng lặp không dừng lại. – Sam

Trả lời

11

EOF không phải là ký tự. EOF là một macro mà getchar() trả về khi nó đến cuối đầu vào hoặc gặp phải một số loại lỗi. ^D không phải là "một ký tự EOF". Những gì đang xảy ra dưới Linux khi bạn nhấn^D trên một dòng của chính nó là nó đóng dòng, và các cuộc gọi getchar() đạt đến cuối của đầu vào và trả về các EOF vĩ mô. Nếu bạn nhập ^D ở đâu đó ở giữa dòng, luồng không bị đóng, vì vậy, getchar() sẽ trả lại giá trị mà nó đọc và vòng lặp của bạn không thoát.

Xem stdio section of the C faq để có mô tả tốt hơn.

Ngoài ra:

Trên các hệ thống hiện đại, nó không phản ánh bất kỳ ký tự end-of-file thực tế lưu trữ trong một tập tin; đó là tín hiệu không có sẵn nhiều ký tự.

+0

Tôi đọc kỹ trang web. Theo tôi, nếu tôi gõ '^ D' ở đâu đó ở giữa một dòng, bash sẽ giải quyết'^D'. Kết quả là, chương trình C không nhận được lệnh để đóng luồng. Nếu tôi gõ '^ D' trong một dòng, chương trình C sẽ nhận được lệnh đúng. Tôi có đúng không? – Sam

+1

@qingfeng Có thêm một chút về '^ D' tại đây: http://www.c-faq.com/stdio/eofval.html Nhưng vâng, luồng sẽ không bị đóng trừ khi nó nằm trên một dòng. Giải thích ngắn ở đây: http://stackoverflow.com/a/1516177/851273 –

+6

Khi thiết bị đầu cuối ở chế độ chuẩn, đường truyền không được truyền qua thiết bị tty cho đến khi bạn nhấn enter. Nhấn phím EOF được định cấu hình (^ D theo mặc định) sẽ khiến dữ liệu được truyền ngay lập tức và bất kỳ 'read' nào đang chờ nó quay trở lại với số ký tự có sẵn. Nếu dòng đã có dữ liệu trên đó, thì đây sẽ là một số đọc bình thường, không phải là 0. Nếu dòng là trống, điều này sẽ dẫn đến một số không đọc dài, đó là định nghĩa * * của tình trạng cuối tập tin trên một bộ mô tả tập tin. Do đó, lớp stdio sẽ giải thích nó là trạng thái EOF. –

6

Ngoài câu trả lời của Jon Lin về EOF, tôi không chắc chắn mã bạn viết là những gì bạn dự định. Nếu bạn muốn xem giá trị trả về từ getchar trong biến d, bạn cần thay đổi tuyên bố while của bạn để:

while((d=getchar())!=EOF) { 

Điều này là do các nhà điều hành bất bình đẳng có độ ưu tiên cao hơn chuyển nhượng. Vì vậy, trong mã của bạn, d sẽ luôn là 0 hoặc 1.

+0

Nó rất tốt để bạn trở nên tỉ mỉ. Nhưng tôi chỉ muốn xác minh rằng biểu thức 'd = getchar()! = EOF' là 0 hoặc 1. – Sam

+0

@Sam: Bạn có thể làm rõ rằng bạn đang gán kết quả so sánh bằng cách viết:' while ((d = (getchar()! = EOF))! = 0) 'hoặc là' while ((d = (getchar()! = EOF))) 'để trình biên dịch không ném cảnh báo vào bạn. Cách thay thế phổ biến hơn là 'while ((d = getchar())! = EOF)' gán kết quả của 'getchar()' thành 'd' và sau đó so sánh nó với EOF. Điều đó để tránh cảnh báo trình biên dịch. Nhiều trình biên dịch hiện đại sẽ tạo ra một cảnh báo cho những gì bạn đã viết. –

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