2013-07-15 36 views
5

Giả sử chúng ta có một tập tin văn bản có tên hi.txt nào có chứa chuỗi sau:ra bất ngờ khi sử dụng fseek

ABCde12345

Hãy nói chúng tôi chạy mã này:

int main() { 
    FILE *fp; 
    fp = fopen("hi.txt","r"); 
    if(NULL == fp) { return 1; } 
    fseek(fp,-1, SEEK_END); 
    while (ftell(fp) > 0) { 
    printf("%c",fgetc(fp)); 
    fseek(fp,-4, SEEK_CUR); 
    } 
    fclose(fp); 
    return 0; 
} 

Khi tôi chạy mã này, mã được in: 3EbCd

Khi tôi cố gắng đoán xem nó sẽ in ra sao Tôi nghĩ rằng nó sẽ là 52d. Có ai có thể giải thích những gì đã xảy ra ở đây không?

Trả lời

15

Dường như có ký tự cuối dòng không thể in ở cuối tệp của bạn. Đó là những gì được in đầu tiên. Sau đó, vị trí được chuyển đến 3, Eb. Tại thời điểm này, định vị lại theo -3 không thành công, vì vị trí sẽ trở thành -2. Con trỏ tệp vẫn ở vị trí cũ, tức là tại C được in tiếp theo. Nỗ lực định vị lại sau đây không thành công, do đó, d được in. Việc tái định vị tiếp theo thành công, chấm dứt vòng lặp.

Để phát hiện các tình huống khi fseek bị lờ đi, kiểm tra giá trị trả về của nó, như thế này:

while (ftell(fp) > 0) { 
    printf("%c",fgetc(fp)); 
    // Successful calls of fseek return zero 
    if (fseek(fp,-4, SEEK_CUR)) { 
     // Exit the loop if you can't jump back by 4 positions 
     break; 
    } 
} 
+0

Nó hoạt động !! Cảm ơn !!! – Robert777

4

Đối với tập tin đã mở trong chế độ văn bản bù đắp thông qua với fseek chỉ có ý nghĩa cho các giá trị được trả về bởi ftell. Vì vậy, bù đắp có thể không nhất thiết phải bằng byte. Thử mở tệp ở chế độ nhị phân:

fp = fopen("hi.txt", "rb"); 

và xem kết quả có khác nhau không.

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