2009-11-23 76 views
31

Làm thế nào để bạn có thể xem bản in cuối cùng? Nói cách khác những gì để đưa vào cho EOF? Tôi đã kiểm tra các định nghĩa và nó nói EOF là -1.EOF trong ngôn ngữ lập trình C là gì?

Và nếu bạn nhập Ctrl-D, bạn sẽ không thấy gì cả.

#include <stdio.h> 

int main() { 
int c; 
while((c = getchar() != EOF)) { 
    printf("%d\n", c); 
} 
printf("%d - at EOF\n", c); 
} 
+0

Bạn có muốn làm rõ không? Câu hỏi của bạn là gì? – qrdl

+0

Tôi muốn đưa vào EOF và nhận được để xem printf ("% d - tại EOF \ n", c); –

+0

và EOF được gọi là -1 nhưng nó diễn giải là ba ký tự và đặt ra số 1 –

Trả lời

40

Trên hệ thống Linux và OS X, ký tự được nhập để gây ra EOF là Ctrl - D. Đối với Windows, đó là Ctrl - Z.

Tùy thuộc vào hệ điều hành, ký tự này sẽ chỉ hoạt động nếu đó là ký tự đầu tiên trên một dòng, tức là ký tự đầu tiên sau Nhập. Vì đầu vào của bảng điều khiển thường theo định hướng dòng, hệ thống cũng có thể không nhận dạng được ký tự EOF cho đến sau khi bạn đã theo dõi nó với một số Nhập.

Và có, nếu ký tự đó được nhận dạng là EOF, thì chương trình của bạn sẽ không bao giờ thấy ký tự thực. Thay vào đó, chương trình C sẽ nhận được -1 từ getchar().

+0

Ok nhưng sự khác nhau giữa Ctrl-z và Ctrl-D trên Windows là gì? Ctrl-z = EFO Ctrl-D = giết? –

+0

@ Chris_45: Trên Windows, Ctrl-Z đánh dấu EOF, Ctrl-D chỉ là Ctrl-D (hoặc ký tự 04). @ gotch4: Đó là tiêu chuẩn (nhưng ít được sử dụng) HTML: < kbd >. –

+1

@ Chris_45: Ctrl-D tương ứng với ASCII EOT (kết thúc truyền), tuy nhiên MS-DOS đã sử dụng Ctrl-Z (ASCII SUB) để tương thích với CP/M và Windows thừa hưởng điều đó. Trong CP/M, ký tự EOF thực sự là một ký tự trong tệp, vì tất cả các tệp phải là bội số của 128 ký tự. Ký tự được sử dụng để báo hiệu EOF là đặc trưng cho hệ điều hành không phải là ngôn ngữ lập trình. http://en.wikipedia.org/wiki/End-of-file – Clifford

4

EOF có nghĩa là kết thúc tệp. Đó là một dấu hiệu cho thấy kết thúc của một tập tin là đạt được, và rằng sẽ không có dữ liệu nữa.

Edit:

Tôi đứng sửa chữa. Trong trường hợp này, nó không phải là kết thúc của tập tin. Như đã đề cập, nó được thông qua khi CTRL + d (linux) hoặc CTRL + z (cửa sổ) được thông qua.

+1

-1: có thể có nghĩa là đã xảy ra lỗi. –

+0

Chỉnh sửa không chính xác. Cụm từ "nó được chuyển khi CTRL + d ... được [nhấn]" là vô nghĩa. Khi người dùng gõ ctrl-D, tệp đầu vào được đóng và 'getchar' trả về EOF để cho biết rằng đã kết thúc tệp. Không có ký tự EOF nào được gửi đến tiến trình. –

+0

Ý bạn là dấu hiệu gì? Có một mẫu bit cụ thể không? –

7

Giá trị của EOF là số nguyên âm để phân biệt giá trị "char" nằm trong khoảng từ 0 đến 255. Nó thường là -1, nhưng có thể là bất kỳ số âm nào khác ... theo POSIX thông số kỹ thuật, vì vậy bạn không nên giả sử nó là -1.

Ký tự^D là thứ bạn nhập vào dòng bảng điều khiển trên UNIX/Linux để cho nó kết thúc một cách hợp lý luồng đầu vào. Nhưng trong các ngữ cảnh khác (như khi bạn đang đọc từ một tập tin) nó chỉ là một nhân vật dữ liệu khác. Dù bằng cách nào, ký tự^D (có nghĩa là kết thúc của đầu vào) không bao giờ làm cho nó thành mã ứng dụng.

Như @Bastien cho biết, EOF cũng được trả về nếu getchar() không thành công. Nói đúng ra, bạn nên gọi ferror hoặc feof để xem liệu EOF có biểu thị lỗi hay kết thúc luồng không. Nhưng trong hầu hết các trường hợp, ứng dụng của bạn sẽ làm điều tương tự trong cả hai trường hợp.

+0

Vì vậy, bạn không bao giờ có thể làm cho EOF trên win32 làm cho nó vào mã ứng dụng và xem in cuối cùng? –

+0

@ Chris_45 - Tôi đang nói về ý nghĩa của EOF. Nguyên nhân gốc rễ của lỗi trong "mã ứng dụng" của bạn là một cái gì đó hoàn toàn khác nhau - xem câu trả lời của @ Lucas, –

+0

Trong stdio.h có '#define EOF (-1)' –

26

Bạn nên thay đổi ngoặc của bạn để

while((c = getchar()) != EOF) 

Bởi vì "=" nhà điều hành có độ ưu tiên thấp hơn "! =" Điều hành. Sau đó, bạn sẽ nhận được kết quả mong đợi. Biểu thức của bạn bằng

while (c = (getchar()!= EOF)) 

Bạn nhận được kết quả của hai là đầu ra, vì bạn đang so sánh "c! = EOF". Điều này sẽ luôn luôn trở thành một cho ký tự bạn đã nhập và sau đó "\ n" theo sau bằng cách nhấn trả về. Ngoại trừ lần so sánh cuối cùng trong đó c thực sự là EOF, nó sẽ cung cấp cho bạn 0.

CHỈNH SỬA về EOF: EOF thường là -1, nhưng điều này không được đảm bảo theo tiêu chuẩn.Tiêu chuẩn này chỉ định nghĩa về EOF trong phần 7.19.1:

EOF mà mở rộng để một biểu thức hằng số nguyên , với kiểu int và một giá trị tiêu cực, được trả về bởi một số chức năng để chỉ end-of -file, tức là, không có thêm đầu vào từ luồng;

Giả sử rằng EOF bằng -1, nhưng khi sử dụng EOF, bạn không nên kiểm tra giá trị cụ thể, mà là sử dụng macro.

+4

Chúng tôi có một người chiến thắng. – Pod

+1

Tuyệt vời thêm về không phải lúc nào cũng là -1 .. hầu hết mọi người bỏ qua rằng –

+0

"EOF mở rộng đến một biểu thức hằng số nguyên, với kiểu int và giá trị âm" 'Int' là 32 bit và tín hiệu EOF thành công thường trên giá trị wchar_t của -1 (hoặc 65535) hoặc giá trị char -1 với một * * không liên quan. –

4

Couple của lỗi chính tả:

while((c = getchar())!= EOF)

ở vị trí của:

while((c = getchar() != EOF))

Cũng getchar() đối xử với một chìa khóa trở lại như một đầu vào hợp lệ, vì vậy bạn cần phải đệm nó too.EOF là một điểm đánh dấu để cho biết kết thúc của đầu vào. Nói chung nó là một int với tất cả các bit thiết lập.


#include <stdio.h> 
int main() 
{ 
int c; 
while((c = getchar())!= EOF) 
{ 
    if(getchar() == EOF) 
    break; 
    printf(" %d\n", c); 
} 
    printf("%d %u %x- at EOF\n", c , c, c); 
} 

in:

49 
50 
-1 4294967295 ffffffff- at EOF

cho đầu vào:

 
1 
2 
<ctrl-d> 
+2

Không có lỗi trong mã của bạn? Bạn gọi 'getchar()' hai lần (một lần trong vòng lặp while và một lần trong if), vì vậy đầu vào rất thứ hai sẽ bị mất ... – Heinzi

+0

Bạn đã thử nghiệm tính năng này chưa? Bạn đang gọi getchar hai lần .. – Pod

+0

Nó hoạt động vì getchar thứ hai() được '\ n' từ đánh trở lại. – Lucas

1
#include <stdio.h> 

int main() { 
    int c; 
    while((c = getchar()) != EOF) { //precedence of != is greater than =, so use braces 
     printf("%d\n", c); 
    } 
    printf("%d - at EOF\n", c); 
} 

Tôi nghĩ rằng đây là cách đúng đắn để kiểm tra giá trị của EOF. Và tôi đã kiểm tra đầu ra.

Đối INPUT: abc và Enter tôi đã OUTPUT: 97 98 99 10 (các giá trị ASCII)

Đối ĐẦU VÀO Ctrl-D Tôi đã OUTPUT: -1 - tại EOF. Vì vậy, tôi nghĩ -1 là giá trị cho EOF.

Thử các đầu vào khác thay vì Ctrl-D, như Ctrl-Z. Tôi nghĩ rằng nó thay đổi từ trình biên dịch sang trình biên dịch.

+1

Chắc chắn, 'stdio.h' định nghĩa' EOF' là '-1'. Nhưng điều đó không nên làm bạn quan tâm, bạn cũng không cần phải nhìn vào nó hoặc in nó ra. Chỉ cần kiểm tra EOF trong mã của bạn và để cho trình biên dịch lo lắng về các chi tiết. –

3

nput từ một thiết bị đầu cuối không bao giờ thực sự "kết thúc" (trừ khi thiết bị bị ngắt kết nối), nhưng rất hữu ích để nhập nhiều hơn một "tập tin" vào một thiết bị đầu cuối, do đó, một chuỗi khóa được dành riêng để cho biết kết thúc đầu vào. Trong UNIX bản dịch của tổ hợp phím để EOF được thực hiện bởi trình điều khiển thiết bị đầu cuối, vì vậy một chương trình không cần phải phân biệt các thiết bị đầu cuối với các tệp đầu vào khác. Theo mặc định, trình điều khiển chuyển đổi một ký tự Control-D ở đầu dòng vào một chỉ báo cuối tập tin. Để chèn một ký tự Control-D (ASCII 04) thực tế vào luồng đầu vào, người dùng đứng trước nó với ký tự lệnh "quote" (thường là Control-V). AmigaDOS tương tự nhưng sử dụng Control- \ thay vì Control-D.

Trong hệ điều hành DOS và Windows của Microsoft (và trong CP/M và nhiều hệ điều hành DEC), việc đọc từ thiết bị đầu cuối sẽ không bao giờ tạo ra EOF. Thay vào đó, các chương trình nhận ra rằng nguồn là một thiết bị đầu cuối (hoặc "thiết bị ký tự" khác) và diễn giải một chuỗi ký tự hoặc chuỗi ký tự được đặt trước làm chỉ báo cuối tệp; thông thường nhất là mã ASCII Control-Z, mã 26. Một số chương trình MS-DOS, bao gồm các phần của Microsoft MS-DOS shell (COMMAND.COM) và các chương trình tiện ích hệ điều hành (như EDLIN), xử lý Control-Z trong một tập tin văn bản như đánh dấu sự kết thúc của dữ liệu có ý nghĩa, và/hoặc gắn thêm một Control-Z để kết thúc khi viết một tập tin văn bản.Điều này đã được thực hiện vì hai lý do:

  1. Backward khả năng tương thích với CP/M. Hệ thống tệp CP/M chỉ ghi lại độ dài của tệp trong bội số của "bản ghi 128 byte", do đó, theo quy ước, ký tự Control-Z được sử dụng để đánh dấu kết thúc dữ liệu có ý nghĩa nếu nó kết thúc ở giữa bản ghi. Hệ thống tệp MS-DOS luôn ghi lại độ dài byte chính xác của các tệp, vì vậy điều này không bao giờ cần thiết đối với MS-DOS.

  2. Nó cho phép các chương trình sử dụng cùng một mã để đọc đầu vào từ cả thiết bị đầu cuối và tệp văn bản.

-1
#include <stdio.h> 

int main() { 
    int c; 
    while((c = getchar()) != EOF) { 
     putchar(c); 
    }  
    printf("%d at EOF\n", c); 
} 

sửa đổi mã ở trên để cho rõ ràng thêm về EOF, Nhấn Ctrl + d và putchar được sử dụng để in các tránh char sử dụng printf trong vòng lặp while.

+0

được kiểm tra trên ubuntu 14.04 –

-1
int c; 

while((c = getchar())!= 10) 
{ 
    if(getchar() == EOF) 
     break; 

    printf(" %d\n", c); 
} 
Các vấn đề liên quan