Saltar al contenido

¿El carácter de nueva línea también vacía el búfer?

Ya no necesitas investigar más por otros sitios ya que estás al lugar justo, tenemos la respuesta que necesitas hallar sin problemas.

Solución:

Convertir comentarios en respuesta.

Depende de donde cout va. Si va a una terminal (‘dispositivo interactivo’), entonces no se puede almacenar en búfer por completo; por lo general, se almacena en búfer de línea, lo que significa que los caracteres aparecen después de que se imprime una nueva línea o, en teoría, podrían no almacenarse en búfer. Si va a una canalización o archivo u otro destino no interactivo, el endl fuerza la salida de los datos incluso si la transmisión está completamente almacenada en búfer, como suele suceder.

También quería saber si no proporcioné ni un carácter de nueva línea ni endl, ¿se mostrará la salida en el stdout una vez que llega al final del programa, sé que lo hace para la terminal, pero ¿es aplicable a todos los tipos de stdout?

Sí, cuando la secuencia de archivos se cierra al final (normal) del programa, la salida pendiente se eliminará. También se vaciará cuando el búfer esté lleno. Si el programa se aborta, la salida pendiente generalmente no se eliminará.

La configuración predeterminada para los objetos de flujo estándar de C ++ (std::cin, std::cout, std::cerr, y std::clog) es que están sincronizados con los correspondientes flujos C (stdin, stdout, y stderr). La sincronización significa que el acceso alterno de las secuencias C ++ y C da como resultado un comportamiento coherente. Por ejemplo, se espera que este código produzca el string hello, world:

std::cout << "hel";
fprintf(stdout, "lo,");
std::cout << " wo";
fprintf(stdout, "rld");

El estándar C ++ no impone ningún mandato sobre cómo se implementa esta sincronización. Una forma de implementarlo es deshabilitar cualquier almacenamiento en búfer para std::cout (y familia) y acceder de inmediato stdout. Es decir, el ejemplo anterior podría escribir inmediatamente los caracteres individuales en stdout.

Si los personajes están realmente escritos en stdout la configuración predeterminada para el modo de almacenamiento en búfer para stdout Sería usado. No puedo encontrar una especificación en el estándar, pero normalmente el predeterminado para el modo de almacenamiento en búfer de stdout es _IOLBF cuando está conectado a una secuencia interactiva (por ejemplo, una consola), es decir, el búfer se vacía al final de las líneas. El valor predeterminado para escribir en un archivo suele ser _IOFBF, es decir, la salida se vacía cuando se escribe un búfer completo. Como resultado, escribir una nueva línea en std::cout podría resultar en que el búfer se vacíe.

Los flujos en C ++ normalmente están configurados para ser almacenados en búfer. Es decir, escribir una nueva línea en un archivo generalmente no hará que la salida aparezca inmediatamente (solo aparecería inmediatamente si el carácter provocó que el búfer se desbordara, la secuencia está configurada para no tener búfer). Dado que la sincronización con stdout a menudo es innecesario, por ejemplo, cuando un programa siempre usa std::cout escribir en la salida estándar, pero hace que la salida a la salida estándar se ralentice drásticamente (deshabilitar el almacenamiento en búfer para la transmisión los hace lento) la sincronización se puede desactivar:

std::ios_base::sync_with_stdio(false);

Esto deshabilita la sincronización para todos los objetos de flujo. Para una mala implementación, no podría haber ningún efecto, mientras que una buena implementación permitirá el almacenamiento en búfer para std::cout lo que resulta en una aceleración sustancial y probablemente también deshabilita el almacenamiento en búfer de línea.

Una vez que una secuencia de C ++ se almacena en búfer, no hay una forma incorporada de hacer que se vacíe cuando se escribe una nueva línea. La razón principal de esto es que lidiar con el almacenamiento en búfer de línea requeriría la inspección de cada carácter por parte del búfer de flujo, lo que inhibe de manera efectiva las operaciones masivas en los caracteres y, por lo tanto, causa una ralentización sustancial. Si es necesario, el búfer de línea se puede implementar a través de un búfer de flujo de filtrado simple. Por ejemplo:

class linebuf: public std::streambuf 
    std::streambuf* sbuf;
public:
    linebuf(std::streambuf* sbuf): sbuf(sbuf) 
    int_type overflow(int_type c) 
        int rc = this->sbuf->sputc(c);
        this->sbuf->pubsync();
        return rc;
    
    int sync()  return this->sbuf->pubsync(); 
;
// ...
int main() 
    std::ios_base::sync_with_stdio(false);
    linebuf sbuf(std::cout.rdbuf());
    std::streambuf* origcout = std::cout.rdbuf(&sbuf);

    std::cout << "linenbufferedn";

    std::cout.rdbuf(origcout); // needed for clean-up;

tl; dr: el estándar C ++ no tiene un concepto de almacenamiento en búfer de línea, pero puede obtenerlo cuando la E / S estándar se sincroniza desde el comportamiento de C de stdout.

Te mostramos reseñas y valoraciones

Recuerda que puedes difundir este ensayo si te fue útil.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *