2012-05-18 22 views
5

Tôi nhận được một lỗi rất lạ khi cố gắng đọc từ một tệp văn bản đơn giản với c fread() gọi.
tôi đã thực hiện một chương trình rất đơn giản để chứng minh rằng lỗi:Tại sao ftell() hiển thị sai vị trí sau khi fread()?

int main(int argc ,char ** argv) { 
    FILE* fh = fopen("adult.txt","r"); 
    if(fh==NULL){ 
    printf("error opening file\n"); 
    exit(0); 
    } 

    int s = 1000; 
    printf("cur before=%d\n",ftell(fh)); 
    char* b = malloc (sizeof(char)*s); 
    int k =fread(b,sizeof(char),s,fh); 
    printf("cur after reading %d bytes =%d\n",k,ftell(fh)); 

    return EXIT_SUCCESS; 
} 

Và những gì tôi nhận được là đầu ra:

cur before=0 
cur after reading 1000 bytes =1007 

Có phải đó là bình thường không? fread trả về số '1000' nhưng con trỏ (với ftell()) hiển thị 1007 và mọi trợ giúp sẽ được đánh giá cao.

Trả lời

10

Điều đó là bình thường.

'\n' có thể được thể hiện bằng hai ký tự, do đó, bạn sẽ nhận được một số sai lệch.

Nếu bạn không muốn điều đó xảy ra, hãy mở finaly ở chế độ nhị phân.

+0

cảm ơn bạn, tôi không biết điều đó. Nhưng tôi không hiểu tại sao sự trở lại của fread() không giống như vị trí con trỏ? – ezzakrem

+1

@ezzakrem Bởi vì 'fread' sẽ giải thích kết thúc của dòng (có thể là hai ký tự) như một ký tự, và báo cáo nó là một. –

4

Từ các tài liệu của ftell:

or binary streams, the value returned corresponds to the number of bytes from the beginning of the file. For text streams, the value is not guaranteed to be the exact number of bytes from the beginning of the file, but the value returned can still be used to restore the position indicator to this position using fseek.

Vì vậy, có, điều này là bình thường.

+0

cảm ơn! – ezzakrem

1

Câu trả lời của Let_Me_Be là chính xác. Tôi chỉ giải thích ở đây rằng ký tự 'End of Line' (EOL) phụ thuộc vào Hệ điều hành cơ bản. Ví dụ, trong Windows nếu bạn mở một tập tin với 'r' (hoặc không nhị phân) thì bất cứ khi nào có một chuỗi '\ r \ n' hệ điều hành sẽ chỉ trả về '\ n'. Tương tự, khi bạn viết một tập tin không được mở ở chế độ nhị phân thì trong Windows nó sẽ viết '\ r \ n' khi bạn chỉ cần viết '\ n'. Đối với các hệ thống Unix, không có bản dịch nào được thực hiện bởi hệ điều hành. Mac cổ điển sẽ sử dụng '\ r' cho ký tự Kết thúc dòng, nhưng tôi nghĩ giờ đây họ sử dụng '\ n' cho EOL. Tôi hy vọng rằng sẽ xóa mật khẩu của '\ n' để được thể hiện (có thể) bằng nhiều ký tự (\ r \ n).

+0

cảm ơn bạn! làm cho nó rất rõ ràng. – ezzakrem

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