Cosa significa svuotare il buffer?


95

Sto imparando il C ++ e ho trovato qualcosa che non riesco a capire:

I buffer di output possono essere svuotati esplicitamente per forzare la scrittura del buffer. Per impostazione predefinita, la lettura dei cinflush cout; coutviene anche svuotato quando il programma termina normalmente.

Quindi svuotare il buffer (ad esempio un buffer di output): questo cancella il buffer cancellando tutto in esso o cancella il buffer inviando tutto in esso? O svuotare il buffer significa qualcosa di completamente diverso?

Risposte:


122

Considera l'idea di scrivere su un file. Questa è un'operazione costosa. Se nel codice scrivi un byte alla volta, ogni scrittura di un byte sarà molto costosa. Quindi un modo comune per migliorare le prestazioni è memorizzare i dati che si stanno scrivendo in un buffer temporaneo. Solo quando sono presenti molti dati il ​​buffer viene scritto nel file. Posticipando le scritture e scrivendo un grande blocco in una volta sola, le prestazioni sono migliorate.

Con questo in mente, svuotare il buffer è l'atto di trasferire i dati dal buffer al file.

Questo cancella il buffer eliminando tutto ciò che contiene o cancella il buffer inviando tutto ciò che contiene?

L'ultimo.


1
Grazie. un'altra cosa. Leggendo cin flushes cout. Questa "lettura cin" significa quando l'utente inserisce qualcosa o quando all'utente viene richiesto di inserire qualcosa?
Mohamed Ahmed Nabil

4
La lettura di cin avviene quando si utilizza l'operatore di flusso per leggere da cin. In genere si desidera scaricare cout quando si legge perché altrimenti l'input potrebbe apparire prima del prompt.
David Heffernan

1
@DavidHeffernan Per quanto ne so, non hai mai bisogno di svuotare cout prima di cin, perché cin e cout sono legati (Stroustrup, The C ++ Programming Language, [io.tie]).
Sturmer

24

Hai citato la risposta:

I buffer di output possono essere svuotati esplicitamente per forzare la scrittura del buffer.

Cioè, potrebbe essere necessario "svuotare" l'output per far sì che venga scritto nel flusso sottostante (che può essere un file o, negli esempi elencati, un terminale).

Generalmente, stdout / cout è con buffer di riga: l'output non viene inviato al sistema operativo finché non si scrive una nuova riga o si scarica esplicitamente il buffer. Il vantaggio è che qualcosa di simile std::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endlcausa solo una scrittura nel "file" sottostante invece di sei, il che è molto meglio per le prestazioni. Lo svantaggio è che un codice come:

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

std::cout << "\n";

verrà prodotto .....immediatamente (per l' sleepimplementazione esatta , vedere questa domanda ). In questi casi, ti servirà un ulteriore << std::flushper assicurarti che l'output venga visualizzato.

Leggere i cinflush in coutmodo da non aver bisogno di un flush esplicito per fare questo:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;

In questo modo per (int i = 0; i <5; i ++) {std :: cout << "."; sonno (1); } std :: cout << std :: endl; non stampa ..... subito. Li stampa con 1 millisecondo in mezzo. Lo noterai di più quando usi sleep (1000)
Mohamed Ahmed Nabil

@MohamedAhmedNabil Sembra che tu stia confondendo sleep()(POSIX) con Sleep()(Windows)
tc.

1
Vecchia risposta, ma solo il commento riguarda meno il contenuto e più l'esempio. Ti qualifichi coutcon uno spazio dei nomi (cioè std::cout) ma non lo hai fatto per il endl, che dovrebbe anche richiedere quella qualificazione.
vol7ron

1
Mi piace il tuo esempio Ma pensavo che endl svuota il buffer, ma nel tuo esempio \ n svuota il buffer. Sono confuso.
Naz

1
@Naz \ n non scarica il buffer; il buffer viene scaricato solo alla fine del programma nel suo esempio (il buffer viene sempre scaricato automaticamente alla fine dei programmi C ++). \ n è stato probabilmente utilizzato solo per la formattazione. Inoltre, hai ragione sul fatto che std :: endl svuota il buffer (così fa std :: flush, ma è autoesplicativo).
liamnickell

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.