paulo1205
(usa Ubuntu)
Enviado em 05/09/2017 - 13:40h
Eu estava no celular, por isso não escrevi muito, e não expliquei o problema. Agora que estou no micro, deixe-me explicar.
A saída padrão, que é o destino de operações como
printf(),
putchar() e
puts() utiliza um buffer de saída, que pode acumular o resultado de múltiplas operações de escrita antes de encaminhar tudo o que foi acumulado para a saída real, no dispositivo que estiver associado à saída padrão.
O motivo disso é que escrever na saída final geralmente é uma operação computacionalmente mais cara, pois costuma envolver chamadas ao sistema operacional e operações sobre dispositivos significativamente mais lentos do que a memória (como o console, um emulador de terminal, um canal de comunicação via rede ou mesmo em disco). Além do mais, alguns desses dispositivos são naturalmente orientados a escrever dados em blocos (principalmente disco ou operações que envolvam comunicação de rede), em vez de poucos caracteres ou bytes de cada vez, e os ganhos de usar buffers com tais dispositivos são ainda mais expressivos.
Há três modos de seleção de buffers que podem ser associados a um stream de saída em C ou C++: buffer pleno, buffer orientado a linha ou sem buffer. O buffer pleno acumula dados até ficar completamente cheio, e descarrega os dados no destino final(*) apenas quando isso acontece. O buffer orientado a linha descarrega os dados toda vez que detecta uma quebra de linha ou quando o ambiente de execução detecta uma operação de leitura no terminal; contudo, se a linha for muito longa, ele se comporta como um buffer pleno. Já o modo sem buffer faz com que todas as operações resultem em escrita direta no destino.
Tipicamente, quando um programa em C ou C++ inicia, a saída padrão é programada para operar com buffer orientado a linha, e a saída de erros é programada para operar sem buffer. Você pode alterar esses modos de operação por meio da função
setvbuf(), desde que essa seja a primeira operação feita sobre eles depois que o programa começa a executar, mas eu não recomendo que o faça. Em vez disso, cuide de colocar eventuais quebras de linha ao final de cada escrita, a menos que quebrar a linha atrapalhe a formatação. Em qualquer caso, você pode chamar
fflush() para descarregar imediatamente o buffer que estiver associado ao stream.
----------------
(*) Na verdade, o destino final aqui descrito é do ponto de vista do programa em C. Depois que o sistema operacional é acionado para realizar a escrita, pode ser que ele, por sua própria conta, ainda retenha os dados em outro nível de buffer, sob seu próprio controle, mesmo após ter sinalizado ao programa que o chamou que os dados tinham sido escritos com sucesso.