c++ - significado - std cin
¿Cuál es la diferencia entre cout, cerr, clog of iostream header en c++? ¿Cuándo usar cuál? (8)
Intenté investigar la diferencia entre cout
, cerr
y cerr
en internet, pero no pude encontrar una respuesta perfecta. Todavía no tengo claro cuándo usarlo. ¿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 sobre cerr
y cerr
, pero el resultado obtenido allí también se puede obtener usando cout
. Entonces, estoy confundido sobre el uso exacto de cada uno.
De un borrador del documento estándar C ++ 17:
30.4.3 Narrow Stream Objects [narrow.stream.objects]
istream cin;
1 El objeto
cin
controla la entrada desde un buffer de flujo asociado con el objetostdin
, declarado en<cstdio>
(30.11.1).2 Después de que el objeto
cin
se inicializa,cin.tie()
devuelve&cout
. Su estado es el mismo que se requiere parabasic_ios<char>::init
(30.5.5.2).
ostream cout;
3 El objeto
cout
controla la salida a un buffer de flujo asociado con el objetostdout
, declarado en<cstdio>
(30.11.1).
ostream cerr;
4 El objeto
cerr
controla la salida a un buffer de flujo asociado con el objetostderr
, declarado en<cstdio>
(30.11.1).5 Una
cerr
inicializado el objetocerr
,cerr.flags() & unitbuf
es distinto de cero ycerr.tie()
devuelve&cout
. Su estado es el mismo que se requiere parabasic_ios<char>::init
(30.5.5.2).
ostream clog;
6 La
clog
objeto controla la salida a un buffer de flujo asociado con el objetostderr
, declarado en<cstdio>
(30.11.1).
Discusión...
cout
escribe en stdout
; cerr
y clog
a stderr
Standard Out ( stdout
) está destinado a recibir salidas no diagnósticas y de errores del programa, como la salida de un procesamiento exitoso que se puede mostrar al usuario final o transmitir en una etapa de procesamiento posterior.
El error estándar ( stderr
) está destinado a la salida de diagnóstico, como mensajes de advertencia y error que indican que el programa no ha producido o no producido la salida que el usuario podría esperar. Esta entrada puede mostrarse al usuario final incluso si los datos de salida se canalizan a una etapa de procesamiento adicional.
cin
y cerr
están vinculados a cout
Ambos se descargan antes de manejar las operaciones de E / S. Esto asegura que las solicitudes enviadas a cout
sean visibles antes de que el programa bloquee la entrada de cin
, y que la salida anterior a cout
se vacíe antes de escribir un error a través de cerr
, que mantiene los mensajes en orden cronológico de su generación cuando ambos se dirigen al mismo terminal / archivo / etc.
Esto contrasta con la clog
: si escribe allí, no se almacenará en el búfer y no estará ligado a nada, por lo que almacenará cantidades de tala decentes de gran tamaño antes de enjuagar. Esto produce el mayor rendimiento de los mensajes, pero significa que los mensajes pueden no ser rápidamente visibles para un posible consumidor leyendo el terminal o siguiendo el registro.
En general, utiliza std::cout
para salida normal, std::cerr
para errores y std::clog
para "logging" (que puede significar lo que quiera que signifique).
La principal diferencia es que std::cerr
no está almacenado 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
std::cerr
corresponden a stderr
(excepto que std::clog
está almacenado en búfer).
La diferencia de estas 3 secuencias es el almacenamiento en búfer.
- Con cerr, el resultado se vacia
- inmediatamente (porque cerr no usa el buffer).
- Con la obstrucción, los flujos de salida
- después de que termine su función actual.
- Llamar explícitamente a la función flush.
- Con cout, el resultado se vacia
- después de haber llamado a cualquier flujo de salida (cout, cerr, clog).
- después de que termine su función actual.
- Llamar explícitamente a la función flush.
Compruebe el siguiente código y ejecute DEBUG en 3 líneas: f (std :: clog), f (std :: cerr), f (std :: out), luego abra 3 archivos de salida para ver qué sucedió. Puedes cambiar 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";
}
Tanto cout como clog están almacenados en el búfer, pero cerr no está protegido y todos estos son objetos predefinidos que son instancias de la clase ostream. El uso básico de estos tres son cout se usa para entrada estándar mientras que clog y cerr se usan para mostrar errores. El principal punto por el que cerr no está almacenado en el 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 mostrar ese error inmediatamente, lo cual puede hacerse de manera efectiva.
Por favor, corríjame si estoy equivocado.
cout se usa generalmente para mostrar algunas declaraciones en la pantalla del usuario. ex-: cout << "Arlene Batada";
salida:
Arlene Batada
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 del programa real, 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.
Flujo de salida estándar (cout): cout
es la instancia de la clase ostream
. cout
se usa para producir salida en el dispositivo de salida estándar que generalmente es la pantalla de visualización. Los datos que se deben mostrar en la pantalla se insertan en la secuencia de salida estándar ( cout
) utilizando el operador de inserción ( <<
).
Flujo de error estándar no protegido (cerr): cerr
es el flujo de error estándar que se utiliza para generar los errores. Esta es también una instancia de la clase ostream
. Como cerr
está tamponado , se usa cuando necesitamos mostrar el mensaje de error de inmediato. No tiene ningún búfer para almacenar el mensaje de error y mostrarlo más tarde.
Flujo de error estándar almacenado (obstrucción): Esta es también una instancia de la clase ostream
y se utiliza 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 por completo.
lectura adicional: basic-input-output-c
cerr no requiere un búfer, por lo que es más rápido que los otros y no utiliza la memoria que usa cout , pero como cout está almacenado en búfer, es más útil en algunos casos. Asi que:
- Use cout para la salida estándar.
- Use cerr para mostrar los errores.
- Utilice la obstrucción para el registro.