2009-11-24 32 views
15

Tôi có một đoạn mã nhỏ bên dưới mà tôi đang chạy bằng cách sử dụng PellesC.Tại sao không getchar() nhận ra trở lại như EOF trên bàn điều khiển?

Khi mã được thực thi và tôi đã nhập một vài ký tự vào bảng điều khiển, tôi nhấn enter.

Bạn có thể giải thích cho tôi tại sao dòng printf("%ld\n", nc); dường như không được thực thi? Vì không có đầu ra nào được ghi vào bàn điều khiển.

#include <stdio.h> 

int main(void) 
{ 
    long nc = 0; 

    while(getchar() != EOF) 
    { 
     ++nc; 
    } 

    printf("%ld\n", nc); 
} 

Tôi đã quyết định tìm hiểu kỹ lưỡng bằng cách sử dụng cuốn sách R & R và tôi cảm thấy xấu hổ khi nói ví dụ cơ bản này khiến tôi bối rối.

Trả lời

33

Nhấn enter không thực sự gây ra một EOF ("kết thúc tệp"). Bạn phải báo hiệu rằng bạn đã hoàn thành xong việc cung cấp đầu vào; trên Unix, bạn thường làm điều đó bằng cách nhấn CtrlD. Trên Windows, tôi tin rằng đó là CtrlZ tiếp theo là nhập, nhưng tôi thực sự không chắc chắn về điều đó.

+1

Tôi thực sự đang sử dụng Windows và Ctrl + Z là chính xác. Cảm ơn, tôi không bao giờ mới. –

+0

nó ** là ** ctrl + z –

4

Bạn kết thúc dữ liệu nhập của mình và bạn đang sử dụng hệ thống nào?

Nếu bạn đang nhấn tổ hợp phím điều khiển 'gián đoạn' hoặc 'giết', thì có khả năng bạn đang giết quá trình của mình trước khi có thể in.

Nếu bạn sử dụng một cái gì đó như Ctrl-D trên unix hoặc Ctrl-Z ở đầu của một dòng trên cửa sổ thì điều này sẽ báo hiệu 'kết thúc của đầu vào' mà không giết chết quá trình.

Bạn cũng có thể thử chuyển hướng đầu vào của mình từ tệp thử nghiệm. ví dụ:

myprogram <input.txt 
1

"Nhấn enter"? Chu trình trong mã của bạn tiếp tục lặp lại cho đến khi nó đạt đến điểm đánh dấu cuối tệp. "Nhấn enter" sẽ không dẫn đến EOF. Nếu bạn muốn mô phỏng EOF từ bàn phím, hãy tham khảo tài liệu cho thiết bị đầu cuối của bạn. Trong Windows, ví dụ, bạn phải nhấn Ctrl + Z để tạo EOF.

0

getchar() trả về một giá trị từ tiêu chuẩn trong (thường là bàn phím). Tôi không nhớ những gì nhân vật EOF sẽ bản đồ, nhưng bạn có thể không thể gõ nó.

+1

EOF không ánh xạ tới bất kỳ ký tự nào. EOF có giá trị âm, 'getchar()' trả về giá trị của ký tự tiếp theo trong dòng 'stdin' được đúc thành' unsigned char' ... do đó một giá trị dương ... hoặc EOF – pmg

+0

** getchar (3) * * là một hàm 'int', trả về' EOF' (thường -1) để báo hiệu kết thúc của tập tin. 'EOF' không phải là một ký tự, và đây là lý do' getchar() 'trả về' int' thay vì 'char'. –

4

Trên Windows, CTRL-Z hoặc F6 sẽ báo hiệu kết thúc tệp.

2

ENTER được viết bằng mã là '\n'. Hãy thử điều này

#include <stdio.h> 

int main(void) 
{ 
    long nc = 0; 

    /* count chars, except for ENTER */ 
    while(getchar() != '\n') 
    { 
     ++nc; 
    } 

    printf("%ld\n", nc); 
    return 0; 
} 
18

Bạn sẽ chỉ nhận được một EOF từ dòng khi kết thúc tập tin được đạt tới, không cuối dòng. Cách bạn báo hiệu phần cuối của tệp phụ thuộc vào cài đặt hệ điều hành và thiết bị đầu cuối của bạn.

Nó thường CTRLd trên hệ thống UNIX-type và CTRLz trên Windows. Đối với UNIX ở chế độ nấu chín (chế độ nhập thông thường), bạn thường sẽ phải nhập nó làm ký tự đầu tiên của một dòng và làm theo nó bằng một dòng mới (ENTER).

Với Windows, CTRLz có thể được nhập bất cứ nơi nào trên dòng, nhưng vẫn cần phải được theo sau bởi một dòng mới.

Trong UNIX, ký tự thực tế để thông báo cho giao diện đầu cuối mà bạn muốn gửi EOF có thể được đặt bằng lệnh stty. Nếu bạn thực hiện stty -a, bạn sẽ thấy một cái gì đó như:

speed 38400 baud; rows 45; columns 150; line = 0; 
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; 
eol = <undef>; eol2 = <undef>; swtch = ^Z; start = ^Q; 
stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; 
flush = ^O; min = 1; time = 0; -parenb -parodd cs8 -hupcl 
-cstopb cread -clocal -crtscts -ignbrk brkint -ignpar -parmrk 
-inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany 
-imaxbel opost -olcuc -ocrnl onlcr -onocr -onlret -ofill 
-ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo 
-echoe -echok -echonl -noflsh -tostop -echoctl -echoke 

Bạn có thể nhìn thấy ở cuối dòng thứ hai mà eof được thiết lập để ^D (CTRLd). Bạn có thể thay đổi điều này với:

stty eof ^x 

để đặt nó vào CTRLx, ví dụ. Bạn cũng có thể đặt một số lượng lớn các thứ khác, hầu hết trong số đó sẽ làm cho thiết bị đầu cuối hiện tại của bạn không sử dụng được, vì vậy hãy cẩn thận :-)

Tóm lại, nếu bạn muốn báo hiệu chương trình của mình là xong, hãy sử dụng CTRLd cho UNIX (hoặc kiểm tra stty nếu điều đó không hoạt động) hoặc CTRLz cho Windows. Nếu bạn muốn chỉ nhận được một dòng của đầu vào, sử dụng ký tự \n trong mã của bạn như sau:

#include <stdio.h> 
int main (void) { 
    long nc = 0; 
    while(getchar() != '\n') 
     ++nc; 
    printf("%ld\n", nc); 
    return 0; 
} 
+0

không sử dụng '^ X' trong unix vì nó được sử dụng trong trình điều khiển tty để gửi' SIGSTOP' tới các tiến trình đầu cuối và sẽ xung đột với ký tự 'EOF'. Cũng trong chế độ nấu chín, unix nhận ra '^ D' là EOF luôn, mà không cần phải sử dụng nhập trước (sau đó, ** nó không được nhận dạng ** ở chế độ thô). Điều gì xảy ra là một '^ D' làm cho một thành công đọc mà không trở lại, và đôi khi bạn sẽ cần một lần thứ hai'^D' để thực hiện ** đọc (2) ** gọi lại hệ thống 0 ký tự ('EOF' trong unix được công nhận là một đọc của 0 ký tự). –

+0

@Luis, CTRL-X chỉ là một ví dụ để hiển thị cách thay đổi nó, với cảnh báo liên quan đến khả năng làm cho thiết bị đầu cuối không phản hồi. – paxdiablo

0

EOF Working

Viết đầu vào của bạn và nhấn Enter sau đó ctrl + z cho Windows và ctrl + d cho Unix rồi nhấn Enter. Tương tự bạn có thể thấy trong Hình ảnh i đính kèm. Điều đó chắc chắn sẽ xảy ra.

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