2017-12-18 135 views
5

cout là luồng được lưu vào bộ đệm. Điều này có nghĩa là dữ liệu sẽ được ghi vào bộ đệm và sẽ được in khi luồng được xóa, chương trình đã kết thúc hoặc khi bộ đệm được điền đầy.Tại sao cout xuất hiện ngay lập tức?

Tôi đã thực hiện một chương trình nhỏ để kiểm tra cách hoạt động, nhưng tôi không hiểu tại sao nó in ngay cả trước khi bất kỳ điều kiện nào ở trên được đáp ứng.

#include <iostream> 
#include <ctime> 
using namespace std; 

int main() 
{ 
    cout << "Test"; 
    float secs = 5; 
    clock_t delay = secs * CLOCKS_PER_SEC; 
    clock_t start = clock(); 
    while (clock() - start < delay) { } 
    return 0; 
} 

Khi chạy, "Kiểm tra" được xuất trước khi bắt đầu vòng lặp.

Tại sao đầu ra của tôi không được lưu vào bộ đệm cho đến khi chương trình kết thúc?

+2

Hãy thử 'std :: ios :: sync_with_stdio (false);' trước khi bạn in. – scohe001

+1

std :: ios :: sync_with_stdio (sai); hoạt động tuyệt vời, cảm ơn! Nhưng tại sao? –

+0

Xem câu trả lời của tôi bên dưới – scohe001

Trả lời

4

Có một cuộc thảo luận tuyệt vời về điều này trên here.

Từ một trong những câu trả lời:

Mỗi C ​​++ dòng sử dụng một đối tượng dòng đệm liên quan để thực hiện đệm.

Khi std::cout được tạo, nó sử dụng bộ đệm luồng được liên kết với đối tượng stdout, được khai báo trong <cstdio>. Theo mặc định, các hoạt động trên std::cout có thể được trộn tự do với các chức năng đầu ra <cstdio> như std::printf().

Trong điều kiện thực tế, đồng bộ hóa thường có nghĩa là đối tượng iostream chuẩn và đối tượng stdio chuẩn chia sẻ bộ đệm. - IS

Nếu std::ios_base::sync_with_stdio(false) được gọi (trước khi bất kỳ hoạt động đầu vào hoặc đầu ra nào trên luồng chuẩn), luồng C++ chuẩn hoạt động độc lập với luồng C chuẩn (tức là chúng chuyển sang bộ đệm luồng riêng).

Để biết thêm, hãy xem trang tham chiếu chức năng sync_with_stdio trên cppreference.

Từ trang đó, chức năng ...

Sets liệu tiêu chuẩn C++ suối được đồng bộ hóa với tiêu chuẩn C suối sau mỗi lần hoạt động đầu vào/đầu ra.

... Trong thực tế, điều này có nghĩa là các luồng C++ được đồng bộ hóa không bị chặn và mỗi thao tác I/O trên luồng C++ được áp dụng ngay cho bộ đệm dòng C tương ứng. Điều này làm cho nó có thể tự do trộn C++ và C I/O.

Tuy nhiên, hãy cẩn thận gọi chức năng này sau đó đã được đọc hoặc viết:

Nếu chức năng này được gọi sau khi I/O đã xảy ra trên dòng tiêu chuẩn, hành vi này là thực hiện xác định : triển khai từ không có hiệu lực để phá hủy bộ đệm đọc.

2

Ngoài ra còn có một cuộc trò chuyện tuyệt vời khác here. Điều này dường như liên quan đến một số điều scohe001 được đề cập, tuy nhiên có một chút khác biệt, vì vậy tôi sẽ đặt nó vào câu trả lời của chính nó.

Liên quan đến câu trả lời ở trên là this đăng trên diễn đàn đó, nói về cách bộ đệm bị xóa tùy thuộc vào mã xung quanh khác. Hàm std :: cout được gắn với các hàm stream khác, và các hàm thư viện c bình thường như scohe001 đã đề cập. Vì vậy, nếu một cái gì đó được gọi là nó được gắn với, bộ đệm của nó sẽ tuôn ra trước khi tiếp tục.

Bạn có biên dịch với gcc trên Linux hoặc chạy trong môi trường cửa sổ nào đó không? Bài đăng này here từ diễn đàn đó ở trên nói về các chức năng cụ thể của OS và ngủ() từ cửa sổ có thể khiến bộ đệm bị xóa. Nếu không bình thường gcc biên dịch mã C++ sẽ không in bộ đệm bằng cách sử dụng sleep(), miễn là nó không gặp phải bất kỳ mã nào khác có thể xóa bộ đệm trước khi tiếp tục.

Các bài đăng ở trên bao gồm nhiều thông tin, vì vậy tôi sẽ không sao chép và dán thông tin ở đây, vì vậy, hãy tha thứ cho tôi về các vị thế ngăn xếp chồng lên nhau.

Tôi hy vọng thông tin này sẽ giúp ích!

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