2009-12-02 27 views
23

Tôi có một tệp văn bản có các chuỗi trên mỗi dòng. Tôi muốn tăng số lượng cho mỗi dòng trong tệp văn bản, nhưng khi nó đến cuối tệp, rõ ràng là nó cần phải dừng lại. Tôi đã thử làm một số nghiên cứu về EOF, nhưng không thể thực sự hiểu cách sử dụng nó đúng cách.Làm thế nào để sử dụng EOF để chạy qua một tập tin văn bản trong C?

Tôi giả sử rằng tôi cần một vòng lặp while, nhưng tôi không chắc chắn cách thực hiện.

Trả lời

67

Làm thế nào bạn phát hiện EOF phụ thuộc vào những gì bạn đang sử dụng để đọc các dòng:

function     result on EOF or error      
--------     ---------------------- 
fgets()     NULL 
fscanf()     number of succesful conversions 
          less than expected 
fgetc()     EOF 
fread()     number of elements read 
          less than expected 

Kiểm tra kết quả của các cuộc gọi đầu vào cho các điều kiện thích hợp trên, sau đó gọi feof() để xác định nếu kết quả là do để đánh EOF hoặc một số lỗi khác.

Sử dụng fgets():

char buffer[BUFFER_SIZE]; 
while (fgets(buffer, sizeof buffer, stream) != NULL) 
{ 
    // process buffer 
} 
if (feof(stream)) 
{ 
    // hit end of file 
} 
else 
{ 
    // some other error interrupted the read 
} 

Sử dụng fscanf():

char buffer[BUFFER_SIZE]; 
while (fscanf(stream, "%s", buffer) == 1) // expect 1 successful conversion 
{ 
    // process buffer 
} 
if (feof(stream)) 
{ 
    // hit end of file 
} 
else 
{ 
    // some other error interrupted the read 
} 

Sử dụng fgetc():

int c; 
while ((c = fgetc(stream)) != EOF) 
{ 
    // process c 
} 
if (feof(stream)) 
{ 
    // hit end of file 
} 
else 
{ 
    // some other error interrupted the read 
} 

Sử dụng fread():

char buffer[BUFFER_SIZE]; 
while (fread(buffer, sizeof buffer, 1, stream) == 1) // expecting 1 
                // element of size 
                // BUFFER_SIZE 
{ 
    // process buffer 
} 
if (feof(stream)) 
{ 
    // hit end of file 
} 
else 
{ 
    // some other error interrupted read 
} 

Lưu ý rằng biểu mẫu giống nhau cho tất cả chúng: kiểm tra kết quả của thao tác đọc; nếu không thành công, hãy rồi kiểm tra EOF. Bạn sẽ thấy rất nhiều ví dụ như:

while(!feof(stream)) 
{ 
    fscanf(stream, "%s", buffer); 
    ... 
} 

Hình thức này không làm việc theo cách mọi người nghĩ nó, bởi vì feof() sẽ không trở thành sự thật cho đến khi sau bạn đã cố gắng đọc qua cuối cùng của tệp. Kết quả là, vòng lặp thực thi một lần quá nhiều, điều này có thể hoặc có thể không khiến bạn đau buồn.

+0

Tốt, nhưng một số gợi ý của câu trả lời phổ biến này: 1) “Chức năng:' fscanf() 'kết quả trên EOF hoặc lỗi: số chuyển đổi thành công ít hơn mong đợi" tương đương với lỗi "đầu vào với lỗi chuyển đổi định dạng. Đề nghị một cột OTOH nó là một chức năng phức tạp 2) kiểm tra chính tả 3) Đề nghị "xấu Mã" bình luận trên 'while (! Feof (stream))' ví dụ. – chux

10

Một C vòng lặp có thể sẽ là:

#include <stdio.h> 
int main() 
{ 
    int c; 
    while ((c = getchar()) != EOF) 
    { 
     /* 
     ** Do something with c, such as check against '\n' 
     ** and increment a line counter. 
     */ 
    } 
} 

Còn bây giờ, tôi sẽ bỏ qua feof và tương tự như chức năng. Exprience cho thấy rằng nó là quá dễ dàng để gọi nó vào thời điểm sai và xử lý một cái gì đó hai lần trong niềm tin rằng eof vẫn chưa đạt được.

Hư hỏng cần tránh: sử dụng char cho loại c. getchar trả về ký tự tiếp theo cho một số unsigned char và sau đó đến int. Điều này có nghĩa là trên hầu hết các nền tảng [sane] có giá trị là EOF và giá trị "char" trong c không trùng lặp, do đó bạn sẽ không bao giờ vô tình phát hiện EOF cho 'bình thường' char.

+0

thait sẽ không bao giờ hoạt động mà bạn không xác định eof – streetparade

+1

Tôi 'bao gồm' stdio.h. –

+0

xem câu trả lời của tôi, tôi đã xác định một eof – streetparade

0

Bạn nên kiểm tra EOF sau khi đọc từ tệp.

fscanf_s     // read from file 
while(condition)   // check EOF 
{ 
    fscanf_s    // read from file 
} 
Các vấn đề liên quan