Tuy nhiên, các lập trình viên C ++ lưu ý rằng điều luôn xảy ra là cin.eof () không trả về "true" cho đến khi dòng cuối cùng được đọc hai lần.
Đó không phải là những gì đang xảy ra. Các eofbit
vai trò không có vai trò trong việc chuyển đổi sang boolean ( stream::operator bool
(hoặc operator void*
trong c ++ cũ hơn)). Chỉ có badbit
và failbit
có liên quan.
Giả sử bạn đang đọc một tệp chứa các số được phân tách bằng khoảng trắng. Một vòng lặp dựa trên cin.eof()
chắc chắn sẽ là sai hoặc là đầy ắp các if
bài kiểm tra. Bạn không đọc cho đến khi EOF. Bạn đang đọc số. Vì vậy, làm cho mã của bạn thể hiện logic đó:
while (stream >> some_var) {
process_value(some_var);
}
Điều này sẽ hoạt động cho dù dòng cuối cùng của tệp kết thúc bằng 0 42\n
hoặc chỉ 0 42
(không có dòng mới ở cuối dòng cuối cùng trong tệp). Nếu tệp kết thúc bằng 0 42\n
, lần đọc tốt cuối cùng sẽ lấy giá trị 42 và đọc điểm cuối cuối cùng của điểm đánh dấu dòng. Lưu ý rằng điểm đánh dấu EOF chưa được đọc. Các chức năng process_value
được gọi với 42
. Cuộc gọi tiếp theo đến toán tử trích xuất luồng >> đọc EOF và vì không có gì được trích xuất, cả hai eofbit
và failbit
sẽ được đặt.
Mặt khác, tập tin kết thúc bằng 0 42
(không có dòng mới ở cuối dòng cuối cùng). Lần đọc tốt cuối cùng sẽ lấy giá trị 42 kết thúc trên điểm đánh dấu EOF. Có lẽ bạn muốn xử lý 42. Đây là lý do tại sao eofbit
không đóng vai trò trong toán tử chuyển đổi boolean luồng đầu vào. Trong cuộc gọi tiếp theo đến toán tử trích xuất luồng >>, máy móc bên dưới nhanh chóng thấy rằng thiết eofbit
bị đã được đặt. Điều này nhanh chóng dẫn đến việc thiết lập failbit
.
Tại sao đoạn mã đầu tiên luôn không hoạt động đúng?
Bởi vì bạn không nên kiểm tra EOF như điều kiện vòng lặp. Điều kiện vòng lặp sẽ diễn tả những gì bạn đang cố gắng thực hiện, đó là (ví dụ), trích xuất các số từ một luồng.