O que significa esvaziar o buffer?

95

Estou aprendendo C ++ e encontrei algo que não consigo entender:

Os buffers de saída podem ser liberados explicitamente para forçar a gravação do buffer. Por padrão, a leitura é cinliberada cout; couttambém é liberado quando o programa termina normalmente.

Portanto, esvaziando o buffer (por exemplo, um buffer de saída): isso limpa o buffer excluindo tudo nele ou limpa o buffer exibindo tudo nele? Ou esvaziar o buffer significa algo completamente diferente?

Mohamed Ahmed Nabil
fonte

Respostas:

122

Considere gravar em um arquivo. Esta é uma operação cara. Se em seu código você escreve um byte de cada vez, então cada escrita de um byte será muito cara. Portanto, uma maneira comum de melhorar o desempenho é armazenar os dados que você está gravando em um buffer temporário. Somente quando há muitos dados o buffer é gravado no arquivo. Adiando as gravações e gravando um bloco grande de uma vez, o desempenho é aprimorado.

Com isso em mente, liberar o buffer é o ato de transferir os dados do buffer para o arquivo.

Isso limpa o buffer excluindo tudo nele ou limpa o buffer exibindo tudo nele?

O último.

David Heffernan
fonte
1
Obrigado. mais uma coisa. Ler cin flushes cout. Esta "leitura cin" significa quando o usuário insere algo ou quando o usuário é solicitado a inserir algo?
Mohamed Ahmed Nabil
4
Ler cin acontece quando você usa o operador stream para ler cin. Normalmente você deseja liberar cout ao ler, caso contrário, a entrada pode aparecer antes do prompt.
David Heffernan
1
@DavidHeffernan Pelo que eu sei, você nunca precisa liberar cout antes de cin, porque cin e cout estão empatados (Stroustrup, The C ++ Programming Language, [io.tie]).
sturmer
24

Você citou a resposta:

Os buffers de saída podem ser liberados explicitamente para forçar a gravação do buffer.

Ou seja, você pode precisar "liberar" a saída para fazer com que ela seja gravada no fluxo subjacente (que pode ser um arquivo ou, nos exemplos listados, um terminal).

Geralmente, stdout / cout é armazenado em buffer de linha: a saída não é enviada ao sistema operacional até que você escreva uma nova linha ou esvazie explicitamente o buffer. A vantagem é que algo como std::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endlcausa apenas uma gravação no "arquivo" subjacente em vez de seis, o que é muito melhor para o desempenho. A desvantagem é que um código como:

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

std::cout << "\n";

será impresso de .....uma vez (para sleepimplementação exata , consulte esta questão ). Nesses casos, você desejará um adicional << std::flushpara garantir que a saída seja exibida.

Lendo as cinliberações coutpara que você não precise de uma liberação explícita para fazer isso:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;
tc.
fonte
Fazendo isso para (int i = 0; i <5; i ++) {std :: cout << "."; dormir (1); } std :: cout << std :: endl; não imprime ..... imediatamente. Ele os imprime com 1 milissegundo entre eles. Você notará mais quando usar o sono (1000)
Mohamed Ahmed Nabil
@MohamedAhmedNabil Você parece estar confuso sleep()(POSIX) com Sleep()(Windows)
tc.
1
Resposta antiga, mas apenas o comentário é menos sobre o conteúdo e mais sobre o exemplo. Você se qualifica coutcom um namespace (ou seja, std::cout) , mas não o fez para o endl, que também deve exigir essa qualificação.
vol7ron
1
Gosto do seu exemplo. Mas eu pensei que endl libera o buffer, mas no seu exemplo, \ n libera o buffer. Estou confuso.
Naz de
1
@Naz \ n não limpa o buffer; o buffer só é descarregado no final do programa em seu exemplo (o buffer é sempre descarregado automaticamente no final dos programas C ++). \ n provavelmente foi usado apenas para formatação. Além disso, você está certo ao dizer que std :: endl esvazia o buffer (o mesmo acontece com std :: flush, mas isso é autoexplicativo).
liamnickell
4

Limpe o buffer exibindo tudo.

Alex Chamberlain
fonte