¿Cuál es la diferencia entre cout, cerr, obstrucción de la cabecera iostream en c++? ¿Cuándo usar cuál?


Intenté investigar la diferencia entre cout, cerr y clog en Internet, pero no pudo encontrar una respuesta perfecta. Todavía no tengo claro cuándo usar cuál. ¿Puede alguien explicarme, a través de programas simples e ilustrar una situación perfecta sobre cuándo usar cuál?

Visité este sitio que muestra un pequeño programa en cerr y clog, pero la salida obtenida allí también se puede obtener usando cout. Por lo tanto, estoy confundido sobre el uso exacto de cada uno.

Author: Kashif Faraz Shamsi, 2013-05-27

8 answers

stdout y stderr son flujos diferentes, aunque ambos se refieren a la salida de la consola por defecto. Redirigir (canalizar) uno de ellos (por ejemplo, program.exe >out.txt) no afectaría al otro.

Generalmente, stdout debe usarse para la salida real del programa, mientras que toda la información y los mensajes de error deben imprimirse en stderr, de modo que si el usuario redirige la salida a un archivo, los mensajes de información todavía se imprimen en la pantalla y no en el archivo de salida.

 39
Author: riv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-13 20:01:38

Generalmente se usa std::cout para la salida normal, std::cerr para los errores, y std::clog para "registro" (que puede significar lo que quiera que signifique).

La principal diferencia es que std::cerr no está amortiguado como los otros dos.


En relación con la antigua C stdout y stderr, std::cout corresponde a stdout, mientras que std::cerr y std::clog ambos corresponden a stderr (excepto que std::clog está tamponado).

 89
Author: Some programmer dude,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 12:09:18

Cerr no requiere un búfer, por lo que es más rápido que los otros y no usa la memoria que usa cout, pero como cout está en búfer, es más útil en algunos casos. Entonces:

  • Use cout para la salida estándar.
  • Use cerr para mostrar errores.
  • Use clog para el registro.
 9
Author: David Vargas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-07 15:41:53

Flujo de salida estándar (cout): cout es la instancia de la clase ostream. cout se utiliza para producir la salida en el dispositivo de salida estándar que es generalmente la pantalla de visualización. Los datos que se deben mostrar en la pantalla se insertan en el flujo de salida estándar (cout) utilizando el operador de inserción (<<).

Flujo de error estándar sin búfer (cerr): cerr es el flujo de error estándar que se utiliza para generar los errores. Este es también un ejemplo de la ostream clase. Como cerr es sin búfer, se usa cuando necesitamos mostrar el mensaje de error inmediatamente. No tiene ningún búfer para almacenar el mensaje de error y mostrarlo más tarde.

Flujo de error estándar en búfer (clog): Esta es también una instancia de la clase ostream y se usa para mostrar errores, pero a diferencia de cerr, el error se inserta primero en un búfer y se almacena en el búfer hasta que no se llena completamente.

Más información : basic-input-output-c

 5
Author: roottraveller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-12 06:45:20

La diferencia de estos 3 flujos es el búfer.

  1. Con cerr, la salida se descarga
    • inmediatamente (porque cerr no usa buffer).
  2. Con zueco, la salida se descarga
    • después de terminar su función actual.
    • llama explícitamente a la función flush.
  3. Con cout, la salida se descarga
    • después de haber llamado a cualquier flujo de salida (cout, cerr, clog).
    • después de terminar su corriente función.
    • llama explícitamente a la función flush.

Verifique el siguiente código y ejecute DEBUG a través de 3 líneas: f(std::clog), f(std::cerr), f(std::out), luego abra 3 archivos de salida para ver qué sucedió. Puedes intercambiar estas 3 líneas para ver qué pasará.

#include <iostream>
#include <fstream>
#include <string>

void f(std::ostream &os)
{
    std::cin.clear(); // clear EOF flags
    std::cin.seekg(0, std::cin.beg); // seek to begin

    std::string line;
    while(std::getline(std::cin, line))   //input from the file in.txt
        os << line << "\n";   //output to the file out.txt
}

void test()
{
    std::ifstream in("in.txt");
    std::ofstream out("out.txt"), err("err.txt"), log("log.txt");
    std::streambuf *cinbuf = std::cin.rdbuf(), *coutbuf = std::cout.rdbuf(), *cerrbuf = std::cerr.rdbuf(),
                    *clogbuf = std::clog.rdbuf();

    std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!
    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
    std::cerr.rdbuf(err.rdbuf());
    std::clog.rdbuf(log.rdbuf());


    f(std::clog);
    f(std::cerr);
    f(std::cout);

    std::cin.rdbuf(cinbuf);
    std::cout.rdbuf(coutbuf);
    std::cerr.rdbuf(cerrbuf);
    std::clog.rdbuf(clogbuf);
}

int main()
{
    test();
    std::cout << "123";
}
 1
Author: Duc-Viet Ha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-01 04:47:00

De un borrador de documento estándar de C++17:

30.4.3 Objetos de flujo estrecho [estrecho.flujo.objetos]

istream cin;

1 El objeto cin controla la entrada de un búfer de flujo asociado con el objeto stdin, declarado en <cstdio> (30.11.1).

2 Después de inicializar el objeto cin, cin.tie() devuelve &cout. Por lo demás, su estado es el mismo que el requerido para basic_ios<char>::init (30.5.5.2).

ostream cout;

3 El objeto cout controla salida a un búfer de flujo asociado con el objeto stdout, declarado en <cstdio> (30.11.1).

ostream cerr;

4 El objeto cerr controla la salida a un búfer de flujo asociado con el objeto stderr, declarado en<cstdio> (30.11.1).

5 Después de inicializar el objeto cerr, cerr.flags() & unitbuf es distinto de cero y cerr.tie() devuelve &cout. Por lo demás, su estado es el mismo que el requerido para basic_ios<char>::init (30.5.5.2).

ostream clog;

6 El objeto clog controla la salida a un búfer de flujo asociado con el objeto stderr, declarado en <cstdio> (30.11.1).

Discusión...

cout escribe a stdout; cerr y clog a stderr

Standard Out (stdout) está destinado a recibir salida sin errores y sin diagnóstico del programa, como la salida del procesamiento exitoso que puede mostrarse al usuario final o transmitirse a alguna etapa de procesamiento posterior.

El error estándar (stderr) está destinado al diagnóstico salida, como mensajes de advertencia y error que indican que el programa no ha producido o puede no haber producido la salida que el usuario podría esperar. Esta entrada se puede mostrar al usuario final incluso si los datos de salida se canalizan a una etapa de procesamiento posterior.

cin and cerr are tied to cout

Ambos limpian cout antes de manejar las operaciones de E/S ellos mismos. Esto asegura que las indicaciones enviadas a cout sean visibles antes de que los bloques del programa lean la entrada de cin, y que la salida anterior a cout se vacía antes de escribir un error a través de cerr, lo que mantiene los mensajes en orden cronológico de su generación cuando ambos se dirigen al mismo terminal/archivo/etc..

Esto contrasta con clog - si escribe allí no se almacenará en búfer y no está vinculado a nada, por lo que almacenará en búfer cantidades de registro de tamaño decente antes de enjuagar. Esto produce el mayor rendimiento de mensajes, pero significa que los mensajes pueden no ser rápidamente visibles para un posible consumidor leyendo el terminal o siguiendo el registro.

 1
Author: Tony Delroy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-26 11:28:21

Tanto cout como clog están en búfer pero cerr no está en búfer y todos estos son objetos predefinidos que son instancias de la clase ostream. El uso básico de estos tres son cout se utiliza para la entrada estándar, mientras que clog y cerr se utiliza para mostrar errores. El punto principal por el que cerr no tiene búfer puede ser porque supongamos que tiene varias salidas en el búfer y se menciona una excepción de error en el código, entonces necesita muestre ese error inmediatamente que puede ser hecho por cerr efectivamente.

Por favor corrígeme si me equivoco.

 0
Author: Kashif Faraz Shamsi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-10 14:30:39

Cout se usa generalmente para mostrar algunas instrucciones en la pantalla del usuario. ex- : cout

Salida:

Arlene Batada

 -2
Author: Devendra singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-19 14:43:11