2011-05-09 21 views
7

Estoy trabajando en un programa que hace un uso intensivo de "cout < < strSomething;" para registrar información en la consola. Necesito modificar el programa para que toda la salida de la consola pase a la consola Y a un archivo. Aunque puedo modificar el "cout < <" en nuestro código, hay varias bibliotecas de terceros grandes que también usan "cout < <"; esas bibliotecas no se pueden modificar debido a sus licencias, por lo que modificar todas las referencias a "cout < <" no es una solución. Además, el uso de "wtee.exe" no es posible debido a la forma en que se ejecutan las líneas de comando.Clase personalizada de C++ cout - salida a la consola y al archivo de registro

Estoy usando Visual Studio 2008. He visto la publicación en Google Groups: redirect cout to file, que parece hacer EXACTAMENTE lo que quiero hacer. El único problema es que el código no se compilará. Obtengo errores de C2248 "no puedo acceder al miembro protegido" en las llamadas al método -> desbordamiento() y -> sincronización().

¿Alguien sabría cómo obtener este código para compilar? ¿O una forma alternativa de redirigir cout tanto a la consola como al archivo simultáneamente?

+0

Duplicar, pienso: http://stackoverflow.com/questions/1760726/compose-output-streams – GManNickG

+0

(Que contiene una solución Boost y otra que no es Boost) – GManNickG

+0

Solución inteligente y simple aquí: http: // stackoverflow.com/a/13978705/2662901 – feetwet

Respuesta

1

Los sync llamadas pueden ser reemplazados por pubsync. En cuanto a la llamada overflow, creo que puede ser un error tipográfico. como parece que debería ser una llamada al sputc.

+0

Cambiando compilaciones "sync" a "pubsync". Pero el cambio a "desbordamiento" a "putc" falla. El error C2039 'putc' no es miembro de std :: basic_streambuf <_Elem, _Traits> –

+0

Lo siento, eso fue un error tipográfico. en mi respuesta. Lo corregí a 'sputc'. – Troubadour

+0

En nuestra situación (no se puede usar Boost, no se pueden modificar bibliotecas de terceros), esta era la mejor solución. –

2

si estás desesperado:

#define protected public 
#include <iostream> 
#undef protected 

Este es un truco bruto, pero por lo general funciona.

+8

Quiero vomitar. – Maxpm

+0

En este punto, estoy lo suficientemente desesperado como para tomar incluso un ataque feo. Desafortunadamente, con VS2008, no ayuda. Mismos errores originales –

0

sólo puede utilizar una clase contenedora para hacerlo, algo como esto

#include <iostream> 
#include <fstream> 

... 

class streamoutput 
{ 
    std::ofstream fileoutput; 
    public: 
    streamoutput(char*filename){ 
     fileoutput.open(filename); 
    } 
    ~streamoutput(){ 
     fileoutput.close(); 
    } 
    template<class TOut> streamoutput& operator <<(const TOut& data) 
    { 
     fileoutput << data; 
     std::cout << data; 
     return this; 
    } 
}; 

extern streamoutput cout("logfile.log"); 

declarar cout así y simplemente cambiar toda su #include <iostream> incluir este envoltorio (cout remeber es variable externa lo que tiene que declere en uno de tus códigos fuente también).

+0

Esto funcionará para el código que escribimos, si pudiéramos modificar nuestras líneas #include . Pero esto no funcionará para el código de terceros, que también debe estar usando #include , pero no podemos modificarlo debido a la licencia. –

+0

¡entonces puedes simplemente modificar el archivo iostream! ¡Ninguna lisence puede evitar eso! pero si tiene un código precompilado que es totalmente diferente, pero también puede escribir un programa contenedor que ejecute el suyo y haga que toda la consola funcione para usted. ¡aunque tomará de alguna manera mucho más esfuerzo! – Ali1S232

12

El boost::iostreams::tee_device está hecho para este

#include <boost/iostreams/stream.hpp> 
#include <boost/iostreams/tee.hpp> 

#include <fstream> 
#include <iostream> 

int 
main() 
{ 
    typedef boost::iostreams::tee_device<std::ostream, std::ofstream> Tee; 
    typedef boost::iostreams::stream<Tee> TeeStream; 

    std::ofstream file("foo.out"); 
    Tee tee(std::cout, file); 

    TeeStream both(tee); 

    both << "this goes to both std::cout and foo.out" << std::endl; 

    return 0; 
} 

invocación de ejemplo:

samm$ ./a.out 
this goes to both std::cout and foo.out 
samm$ cat foo.out 
this goes to both std::cout and foo.out 
samm$ 
+0

Esto funciona bien para mí, desafortunadamente, me han pedido que NO incluya Boost como parte de esta aplicación. Gestión, decisión no técnica. Entonces, ¿cómo haces esto en solo std? –

+0

@Jason parece que hay algunas otras respuestas que no usan boost. Buena suerte. –

1

Lo que puede hacer es capturar la std::cout.rdbuf() con un puntero a std::streambuf, entonces creo que debería ser capaz de escribir todas las salidas a std::cout a algún archivo.

0

Lamento calentar esto tan tarde, pero esto debería ser una solución con la redirección de cout a un teebuffer basado en la solución de Dietmar Kühl en grupos de Google.

uso es simplemente

GetSetLog log("myfile.log"); 

Durante el tiempo de vida del objeto "log" todo lo que se escribirá en tanto cout/cerr y presente

https://sourceforge.net/p/getset/code/ci/master/tree/GetSet/GetSetLog.hxx

Cuestiones relacionadas