Що означає змивання буфера?


95

Я вивчаю C ++ і знайшов щось, чого не можу зрозуміти:

Вихідні буфери можна явно змити, щоб примусити буфер записати. За замовчуванням зчитування cinзмивається cout; coutтакож змивається, коли програма закінчується нормально.

Отже, очищення буфера (наприклад, вихідного буфера): чи очищає це буфер, видаляючи все в ньому, чи очищає буфер, виводячи все, що в ньому? Або змивання буфера означає щось зовсім інше?

Відповіді:


122

Подумайте над тим, щоб написати у файл. Це дорога операція. Якщо у своєму коді ви пишете по одному байту за раз, то кожен запис байту буде дуже дорогим. Отже, поширеним способом підвищення продуктивності є зберігання даних, які ви пишете, у тимчасовому буфері. Лише коли даних багато, буфер записується у файл. Відкладаючи запис і записуючи великий блок за один раз, продуктивність покращується.

З огляду на це, змивання буфера є актом передачі даних з буфера у файл.

Чи очищає це буфер, видаляючи все в ньому, чи очищає буфер, виводячи все, що в ньому?

Лист.


1
Дякую. і ще одна річ. Читання cin clush cout. Чи означає це "читання cin", коли користувач щось вводить або коли користувачеві пропонується щось ввести?
Мохамед Ахмед Набіль

4
Читання cin відбувається, коли ви використовуєте оператор потоку для читання з cin. Як правило, ви хочете змити каут, коли читаєте, оскільки інакше введення може з'явитися перед запитом.
Девід Хеффернан

1
@DavidHeffernan Наскільки я знаю, вам ніколи не потрібно змивати cout перед cin, тому що cin і cout пов'язані (Stroustrup, мова програмування C ++, [io.tie]).
міцніший

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;

Роблячи це для (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 змиває буфер. Я збентежений.
Наз

1
@Naz \ n не змиває буфер; буфер змивається лише в кінці програми в його прикладі (буфер завжди автоматично змивається в кінці програм C ++). \ n, швидше за все, просто використовувався для форматування. Крім того, ви маєте рацію, що std :: endl змиває буфер (як і std :: flush, але це зрозуміло).
liamnickell

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.