Что означает очистка буфера?

98

Я изучаю C ++ и обнаружил то, чего не могу понять:

Буферы вывода могут быть явно очищены для принудительной записи буфера. По умолчанию чтение cinсбрасывается cout; coutтакже сбрасывается при нормальном завершении программы.

Итак, очистка буфера (например, буфера вывода): очищает ли это буфер, удаляя все в нем, или он очищает буфер, выводя все в нем? Или промывка буфера означает совсем другое?

Мохамед Ахмед Набиль
источник

Ответы:

123

Рассмотрите возможность записи в файл. Это дорогостоящая операция. Если в коде вы пишете по одному байту за раз, то каждая запись байта будет очень затратной. Таким образом, распространенный способ повышения производительности - хранить данные, которые вы пишете, во временном буфере. Буфер записывается в файл только при большом количестве данных. За счет откладывания записи и записи большого блока за один раз производительность повышается.

Имея это в виду, очистка буфера - это акт передачи данных из буфера в файл.

Очищает ли это буфер, удаляя все в нем, или он очищает буфер, выводя все в нем?

Последний.

Дэвид Хеффернан
источник
1
Спасибо. еще кое-что. Чтение cin промывает cout. Означает ли это "чтение cin", когда пользователь что-то вводит или когда пользователю предлагается что-то ввести?
Мохамед Ахмед Набиль,
4
Чтение cin происходит, когда вы используете оператор потока для чтения из cin. Обычно вы хотите сбросить cout при чтении, потому что в противном случае ввод может появиться перед приглашением.
Дэвид Хеффернан
1
@DavidHeffernan Насколько я знаю, вам никогда не нужно сбрасывать cout перед cin, потому что cin и cout связаны (Stroustrup, Язык программирования C ++, [io.tie]).
Sturmer
24

Вы процитировали ответ:

Буферы вывода могут быть явно очищены для принудительной записи буфера.

То есть вам может потребоваться «очистить» вывод, чтобы он был записан в базовый поток (который может быть файлом или, в перечисленных примерах, терминалом).

Как правило, stdout / cout буферизируется по строке: вывод не отправляется в ОС, пока вы не напишете новую строку или не очистите буфер явно. Преимущество в том, что что-то вроде std::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endlвызывает только одну запись в базовый "файл" вместо шести, что намного лучше для производительности. Недостаток в том, что такой код:

for (int i = 0; i < 5; i++) {
    std::cout << ".";
    sleep(1); // or something similar
}

std::cout << "\n";

будет выводить .....сразу (точную sleepреализацию см. в этом вопросе ). В таких случаях вам понадобится дополнительная, << std::flushчтобы гарантировать отображение вывода.

Чтение cinсбросов, coutпоэтому вам не нужно для этого явного сброса:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;
tc.
источник
Выполнение этого для (int i = 0; i <5; i ++) {std :: cout << "."; сон (1); } std :: cout << std :: endl; не печатает ..... сразу. Он печатает их с интервалом в 1 миллисекунду. Вы заметите это больше, когда спите (1000)
Мохамед Ахмед Набиль,
@MohamedAhmedNabil Вы, кажется, путаете sleep()(POSIX) с Sleep()(Windows)
tc.
1
Старый ответ, но только комментарий, не столько о содержании, сколько о примере. Вы coutсоответствуете пространству имен (т. Е. std::cout), Но не сделали этого для класса endl, что также должно требовать этой квалификации.
vol7ron
1
Мне нравится твой пример. Но я думал, что endl очищает буфер, но в вашем примере \ n очищает буфер. Я смущен.
Naz
1
@Naz \ n не очищает буфер; буфер очищается только в конце программы в его примере (буфер всегда автоматически очищается в конце программ C ++). \ n, скорее всего, использовался только для форматирования. Кроме того, вы правы, что std :: endl очищает буфер (как и std :: flush, но это не требует пояснений).
liamnickell
4

Очистите буфер, выводя все.

Алекс Чемберлен
источник