f là con trỏ trỏ đến tệp nhị phân DATA chứa không quá 100 bản ghi (kiểu cấu trúc) liền nhau. Cho khai báo: struct T{…}; struct T x[100] int i=0, n=0;Đoạn chương trình nào sau đây đọc toàn bộ các bản ghi trong DATA vào x:
Trả lời:
Đáp án đúng: C
**Phân tích câu hỏi:**
Câu hỏi yêu cầu tìm đoạn chương trình đúng để đọc toàn bộ các bản ghi từ một tệp nhị phân vào một mảng cấu trúc. Cần xem xét cách đọc dữ liệu nhị phân, cách kiểm tra điều kiện kết thúc tệp và cách di chuyển con trỏ tệp.
**Đánh giá các phương án:**
* **Phương án A:** Sử dụng `fread` để đọc từng bản ghi và `feof` để kiểm tra điều kiện kết thúc tệp. Tuy nhiên, việc gọi `fread` trước vòng `while` có thể dẫn đến đọc trùng bản ghi cuối cùng nếu `feof(f)` trả về true ngay từ lần đầu. Sau đó, `i++` được gọi ngay sau `x+i++` dễ gây khó hiểu, có thể dẫn đến lỗi logic.
* **Phương án B:** Sử dụng `fseek` và `ftell` để xác định số lượng bản ghi trong tệp, sau đó sử dụng `fread` để đọc toàn bộ dữ liệu vào mảng. Cách này hiệu quả và chính xác.
**Kết luận:**
Phương án B là phương án đúng nhất vì nó xác định chính xác số lượng bản ghi trong tệp và đọc toàn bộ dữ liệu vào mảng một cách hiệu quả.
**Giải thích chi tiết:**
* `fseek(f, 0, SEEK_END);`: Di chuyển con trỏ tệp đến cuối tệp.
* `n = ftell(f) / sizeof(T);`: Tính số lượng bản ghi bằng cách chia kích thước tệp cho kích thước của một bản ghi.
* `fseek(f, 0, SEEK_SET);`: Di chuyển con trỏ tệp trở lại đầu tệp.
* `fread(x, sizeof(T), n, f);`: Đọc `n` bản ghi từ tệp vào mảng `x`.
* `fclose(f);`: Đóng tệp.
Phương án A không tối ưu vì có thể đọc trùng bản ghi cuối cùng và cách dùng `i++` không rõ ràng, làm tăng độ phức tạp.