Ich schreibe einen Code, wo ich die gleichen Daten auf der Konsole und in einer Datei drucken muss. Gibt es eine Möglichkeit, ein gemeinsames Ausgabestreamobjekt zu füllen und es dann auf der Konsole mit cout anzuzeigen und es in eine Datei zu exportieren, indem Sie fstream- und iostream-Bibliotheken verwenden?Gibt es eine Möglichkeit, ein gemeinsames Ausgabe-Stream-Objekt zum Drucken auf der Konsole und einer Datei in C++ zu erstellen?
Antwort
Sicher. Sie würden einfach einen geeigneten Stream-Puffer erstellen, der wahrscheinlich in anderen Stream-Puffern gespeichert wird, in die er intern schreibt. Mit diesem Stream-Puffer erstellen Sie dann eine std::ostream
, in die Sie schreiben.
Zum Beispiel, hier ist eine einfache Implementierung dieses Ansatzes:
#include <streambuf>
#include <ostream>
class teebuf
: public std::streambuf
{
std::streambuf* sb1_;
std::streambuf* sb2_;
int overflow(int c) {
typedef std::streambuf::traits_type traits;
bool rc(true);
if (!traits::eq_int_type(traits::eof(), c)) {
traits::eq_int_type(this->sb1_->sputc(c), traits::eof())
&& (rc = false);
traits::eq_int_type(this->sb2_->sputc(c), traits::eof())
&& (rc = false);
}
return rc? traits::not_eof(c): traits::eof();
}
int sync() {
bool rc(false);
this->sb1_->pubsync() != -1 || (rc = false);
this->sb2_->pubsync() != -1 || (rc = false);
return rc? -1: 0;
}
public:
teebuf(std::streambuf* sb1, std::streambuf* sb2)
: sb1_(sb1), sb2_(sb2) {
}
};
class oteestream
: private virtual teebuf
, public std::ostream {
public:
oteestream(std::ostream& out1, std::ostream& out2)
: teebuf(out1.rdbuf(), out2.rdbuf())
, std::ostream(this) {
this->init(this);
}
};
#include <fstream>
#include <iostream>
int main()
{
std::ofstream fout("tee.txt");
oteestream tee(fout, std::cout);
tee << "hello, world!\n";
}
Ein benutzerdefinierter stream-Puffer könnte hier jedoch übertrieben sein. Speichern in einem 'stringstream' und zweimaliges Ausgeben kann gut genug sein. Wie auch immer, gut. (BTW: Sie hatten diesen Code herumliegen?) – Deduplicator
@Deduplicator: Ja, es gibt eine Lösung, die eine PITA zu verwenden ist und eine richtige Lösung, die schön zu verwenden ist. Wenn Sie den Stream-Puffer in einen 'std :: ostream 'einbinden, ist der Tee-Stream-Puffer sehr nützlich. ... und ja, ich hatte diesen Code herumliegen: Ich tippe nicht _that_ schnell :-) –
Verwenden Sie einen [ 'boost :: iostreams :: tee_device'] (http://www.boost.org/doc/libs/ 1_39_0/libs/iostreams/doc/funktionen/tee.html). – 0x499602D2
Ich würde Ihnen empfehlen, dies in der aufrufenden Umgebung zu tun. –