 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Daniela Weber Guest
|
Posted: Mon Jan 30, 2006 10:15 pm Post subject: Split/duplicate stream |
|
|
Hallo NG,
ich bin schon seit längerem auf der Suche nach einer Methode um streams
suf die Console UND in eine log Datei umzulenken. Mit:
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
ofstream out("my_err.log");
if ( out )
clog.rdbuf(out.rdbuf());
else
cerr << "Error while opening the file" << endl;
clog << "Fehler xxx aufgetreten" << endl;
system("PAUSE");
}
kann ich ja schön in eine Datei schreiben. Ich will aber nun auch
gleichzeitig clog auf cout ausgeben.
Ich stelle mir da eine Klasse a vor, die sowohl cout als auch den
ofstream bedient, so dass
a << "xxx" << 5 << endl; usw. möglich wird. Da muss es doch etwas geben...
Danke schonmal für eure Vorschläge,
Gruß Dani
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Jan 31, 2006 4:01 pm Post subject: Re: Split/duplicate stream |
|
|
Daniela Weber wrote:
| Quote: | ich bin schon seit längerem auf der Suche nach einer Methode
um streams suf die Console UND in eine log Datei umzulenken.
Mit:
#include <cstdlib
#include <iostream
#include <fstream
using namespace std;
int main(int argc, char *argv[])
{
ofstream out("my_err.log");
if ( out )
clog.rdbuf(out.rdbuf());
else
cerr << "Error while opening the file" << endl;
clog << "Fehler xxx aufgetreten" << endl;
system("PAUSE");
}
kann ich ja schön in eine Datei schreiben. Ich will aber nun
auch gleichzeitig clog auf cout ausgeben. Ich stelle mir da
eine Klasse a vor, die sowohl cout als auch den ofstream
bedient, so dass
a << "xxx" << 5 << endl; usw. möglich wird. Da muss es doch etwas geben...
|
Die gewöhnliche Lösung dafür ist ein filtrierender streambuf.
Der streambuf selber enthält Zeiger auf den Zielstreambuf's, und
leitet alle Zeichen weiter auf die Beiden. Das einzige Problem
ist die Fehlerbehandlung; wenn es aber um eine Log-Datei geht,
kann man es vorstellen, dass Fehler in der Log-Datei einfach
ignoriert werden, und also der Fehler-Zustand des filtrierenden
streambuf genau der der Console-Ausgabe nachgibt.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Stefan Näwe Guest
|
Posted: Wed Feb 01, 2006 1:30 pm Post subject: Re: Split/duplicate stream |
|
|
Daniela Weber schrieb:
| Quote: | Hallo NG,
ich bin schon seit längerem auf der Suche nach einer Methode um streams
suf die Console UND in eine log Datei umzulenken. Mit:
#include <cstdlib
#include <iostream
#include <fstream
using namespace std;
int main(int argc, char *argv[])
{
ofstream out("my_err.log");
if ( out )
clog.rdbuf(out.rdbuf());
else
cerr << "Error while opening the file" << endl;
clog << "Fehler xxx aufgetreten" << endl;
system("PAUSE");
}
kann ich ja schön in eine Datei schreiben. Ich will aber nun auch
gleichzeitig clog auf cout ausgeben.
Ich stelle mir da eine Klasse a vor, die sowohl cout als auch den
ofstream bedient, so dass
a << "xxx" << 5 << endl; usw. möglich wird. Da muss es doch etwas geben...
Danke schonmal für eure Vorschläge,
Gruß Dani
Da hat doch Dietmar Kühl vor Ewigkeiten schon mal was zu geschrieben: |
http://tinyurl.com/8sxz5
Stefan
--
Stefan Naewe
naewe.s_AT_atlas_DOT_de
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Daniela Weber Guest
|
Posted: Sun Feb 05, 2006 11:02 pm Post subject: Re: Split/duplicate stream |
|
|
Stefan Näwe schrieb:
Hallo Stefan, danke für den Link.
Aber irgendwie will das bei mir mit mingw nicht compilieren. Und zwar
wegen dem protected overflow und sync:
typename _Traits::int_type std::basic_streambuf<_CharT,
_Traits>::overflow(typename _Traits::int_type) [with _CharT = char,
_Traits = std::char_traits<char>]' is protected within this context
Eine der betreffenden Zeilen:
if (i_sb1->overflow(c) == EOF || i_sb2->overflow(c) == EOF)
Hat da jemand eine Idee oder funktioniert das Beispiel bei jemandem ?
Gruß Dani
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Daniela Weber Guest
|
Posted: Sun Feb 05, 2006 11:02 pm Post subject: Re: Split/duplicate stream |
|
|
Hallo NG,
ich hab noch etwas gesucht und http://tinyurl.com/9b4no gefunden was bei
mir funktioniert.
Danke für Hinweise, welche schlußendlich zum Erfolg führten
Gruß Dani
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Mon Feb 06, 2006 6:02 pm Post subject: Re: Split/duplicate stream |
|
|
Daniela Weber <clarete (AT) web (DOT) de> writes:
| Quote: | Da hat doch Dietmar Kühl vor Ewigkeiten schon mal was zu geschrieben:
http://tinyurl.com/8sxz5
Aber irgendwie will das bei mir mit mingw nicht compilieren. Und zwar
wegen dem protected overflow und sync:
typename _Traits::int_type std::basic_streambuf<_CharT,
_Traits>::overflow(typename _Traits::int_type) [with _CharT = char,
_Traits = std::char_traits<char>]' is protected within this context
|
Dietmars Code stammt aus dem Jahr 1996 ... Damals war er korrekt.
| Quote: | Eine der betreffenden Zeilen:
if (i_sb1->overflow(c) == EOF || i_sb2->overflow(c) == EOF)
Hat da jemand eine Idee oder funktioniert das Beispiel bei jemandem ?
|
Ersetze die beiden Aufrufe von overflow()urch solche von sputc():
if (i_sb1->sputc(c) == EOF || i_sb2->sputc(c) == EOF)
Und diejenigen von sync() in teestreambuf::sync() durch Aufrufe von pubsync():
if (i_sb1->pubsync() == EOF || i_sb2->pubsync() == EOF)
Ich würde dann noch
* <iostream>, <istream>, <ostream> bzw. <fstream> #includen statt
<iostream.h> bzw. <fstream>
* wo nötig Namen mit std:: qualifizieren
* beide Vorkommnisse der Anweisung
EOF == 0? 1: 0
durch
traits_type::not_eof(c) bzw. traits_type::not_eof(traits_type::int_type())
ersetzen
* alle übrigen Vorkommnisse von EOF durch traits_type::eof() ersetzen
Vermutlich habe ich etwas übersehen, aber Dietmar liest ja hier mit :-)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
7.e.Q Junior Member
Joined: 24 Apr 2006 Posts: 1
|
Posted: Mon Apr 24, 2006 12:14 pm Post subject: re:Split/duplicate stream |
|
|
Hmm, gut, gut... Hallo! Also ich hab das jetzt mal so implementiert bei mir, und es funktioniert. Jetzt ist zumindest für mich die nächste Frage:
a) ich möchte ein Prefix vor die Ausgabe packen:
Zum Beispiel:
| Code: |
omsgstream msg( std::cout.rdbuf(), "PREFIX: " );
msg << "Hallo" << endl;
|
soll ausgeben
Wie mach ich das?
b) Die Ausgabe soll nur erfolgen, wenn der bool bQuiet != true ist (bQuiet ist Member einer der streambuf-Erben). |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Apr 25, 2006 10:06 am Post subject: Re: re:Split/duplicate stream |
|
|
7.e.Q wrote:
| Quote: | Hmm, gut, gut... Hallo! Also ich hab das jetzt mal so implementiert
bei mir, und es funktioniert. Jetzt ist zumindest für mich die
nächste Frage:
a) ich möchte ein Prefix vor die Ausgabe packen:
Zum Beispiel:
omsgstream msg( std::cout.rdbuf(),
"PREFIX: " );
msg << "Hallo" << endl;
soll ausgeben
[code:1:292ee4ac4d]
PREFIX: Hallo
[/code:1:292ee4ac4d]
Wie mach ich das?
|
Geht auch ganz gut mit einem filtrierenden streambuf. Du musst
halt den Zustand halten, ob du am Zeilanfang bist oder nicht,
und wenn ja, den Präfix ausgeben. So ungefähr (in overflow):
if ( isStartOfLine ) {
dest.sputn( myPrefix.data(), myPrefix.size() ) ;
}
// ...
isStartOfLine = charOutput == '\n' ;
// Für's nächste Mal.
| Quote: | b) Die Ausgabe soll nur erfolgen, wenn der bool bQuiet != true ist
(bQuiet ist Member einer der streambuf-Erben).
|
Das kann man auch im filtrierenden streambuf machen. Dann aber
wird trotzem alles formattiert; nur die Ausgabe selbe entfällt.
In solchen Fällen benutze ich lieber einen ostream-Wrapper, eine
Klasse, die einen Zeiger auf einem ostream (oder gerade nicht,
wenn es ausgeschaltet ist) hält, und einen template operator<<
hat:
template< typename T >
LogWrapper&
operator<<( LogWrapper& dest, T const& obj )
{
std::ostream* s = dest.stream() ;
if ( s != NULL ) {
*s << obj ;
}
return *this ;
}
Damit wird auch das Formattieren unterdruckt, falls Logging
nicht eingeschaltet ist.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|