2010-02-09 6 views
10

Tại sao mã bên dưới không hoạt động? Ý tôi là, nó hiển thị tất cả các loại ký tự lạ trên đầu ra của bàn điều khiển.Tại sao tôi cần xóa luồng I/O của mình để có được kết quả chính xác?

#include <stdio.h> 
char mybuffer[80]; 
int main() 
{ 
    FILE * pFile; 
    pFile = fopen ("example.txt","r+"); 
    if (pFile == NULL) perror ("Error opening file"); 

    else { 
     fputs ("test",pFile); 

     fgets (mybuffer,80,pFile); 
     puts (mybuffer); 
     fclose (pFile); 
     return 0; 
    } 
} 

Tuy nhiên, mã bên dưới hoạt động tốt.

#include <stdio.h> 
char mybuffer[80]; 
int main() 
{ 
    FILE * pFile; 
    pFile = fopen ("example.txt","r+"); 
    if (pFile == NULL) perror ("Error opening file"); 

    else { 
     fputs ("test",pFile); 
     fflush (pFile);  
     fgets (mybuffer,80,pFile); 
     puts (mybuffer); 
     fclose (pFile); 
     return 0; 
    } 
} 

Tại sao tôi cần xóa luồng để có được kết quả chính xác?

Trả lời

12

Bởi vì tiêu chuẩn nói như vậy (§7.19.5.3/5):

Khi một tập tin được mở ra với chế độ cập nhật ('+' là thứ hai hoặc ký tự thứ ba trong danh sách ở trên đối số chế độ giá trị), cả đầu vào và đầu ra có thể là được thực hiện trên luồng được liên kết. Tuy nhiên, sản lượng sẽ không được trực tiếp tiếp theo đầu vào mà không một can thiệp gọi hàm fflush hoặc đến một vị trí tập tin function (fseek, fsetpos, hoặc tua lại), và đầu vào không được trực tiếp tiếp theo sản lượng mà không an cuộc gọi can thiệp vào chức năng định vị tệp , trừ khi thao tác nhập gặp phải tệp kết thúc.

Có lý do cho việc này: đầu ra và đầu vào thường được đệm riêng. Khi có một tuôn ra hoặc tìm kiếm, nó đồng bộ hóa các bộ đệm với các tập tin, nhưng nếu không nó có thể cho phép họ có được ra khỏi đồng bộ. Điều này giúp cải thiện hiệu suất (ví dụ: khi bạn đọc, nó không phải kiểm tra xem vị trí bạn đọc từ đã được viết hay chưa kể từ khi dữ liệu được đọc vào bộ đệm).

+0

Thx rất nhiều !!!!!! – Jaebum

+0

Nhưng tại sao đầu ra của nguồn thứ hai không phải là "kiểm tra"? Nó chỉ hiển thị không có gì .. – Jaebum

+1

@Lee: Đơn giản, bạn đọc nó từ điểm mà bạn rời khỏi văn bản, bạn cần phải tìm kiếm lại để bắt đầu cho rằng để làm việc. – falstro

2

vì tệp io hoạt động bằng bộ đệm. Điều này chỉ được ghi vào đĩa khi bạn xóa nó, bạn viết một ký tự/n hoặc bạn điền vào bộ đệm.

Vì vậy, trong trường hợp đầu tiên, tệp của bạn không có gì khi bạn đọc nó.

+0

Nhưng nó vẫn không hoạt động ngay cả khi tôi sử dụng "test \ n" thay vì "test". – Jaebum

+0

Câu trả lời sai về vấn đề này: Viết '\ n' vào tệp không có tác dụng gì cả; bạn phải xóa tệp hoặc ghi nhiều dữ liệu mà thư viện C sẽ tự xóa (thường là 4KiB). –

+0

Tôi nghĩ rằng \ n bit phụ thuộc vào việc thực hiện - MS, ít nhất là cho mã C++. – gbjbaanb

7

Khi sử dụng tệp có chế độ đọc/ghi, bạn phải gọi fseek/fflush trước các hoạt động i/o khác nhau.

Xem câu trả lời này trên why fseek or fflush is always required...

+0

Thx; Tôi nên tìm kiếm khó hơn – Jaebum