Piszę kod, w którym muszę wydrukować te same dane na konsoli i do pliku. Czy istnieje sposób wypełnienia wspólnego obiektu strumienia wyjściowego, a następnie wyświetlenia go na konsoli przy użyciu cout i wyeksportowania go do pliku przy użyciu bibliotek fstream i iostream?Czy istnieje sposób utworzenia wspólnego obiektu strumienia wyjściowego do wydrukowania na konsoli i do pliku w języku C++?
Odpowiedz
Pewnie. Po prostu utworzysz odpowiedni bufor strumienia, który prawdopodobnie przechowuje do innych buforów strumieniowych, które zapisuje wewnętrznie. Używając tego bufora strumieniowego, utworzysz std::ostream
do którego piszesz.
Na przykład, tutaj jest prosta realizacja tego podejścia:
#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";
}
Niestandardowy bufor strumienia może być tu jednak przesadzony. Zapisywanie do 'stringstream' i wysyłanie tego dwa razy może być wystarczająco dobre. W każdym razie, dobrze. (BTW: Miałeś ten kod leżący w pobliżu?) – Deduplicator
@Deduplicator: tak, istnieje rozwiązanie, które jest PITA do użycia i odpowiednie rozwiązanie, które jest przyjemne w użyciu. Zawijanie bufora strumienia do 'std :: ostream' sprawia, że bufor strumienia tee jest całkiem przyjemny w użyciu. ... i, tak, miałem ten kod leżący: nie piszę tego szybko :-) –
Użyj [ 'boost :: iostreams :: tee_device'] (http://www.boost.org/doc/libs/ 1_39_0/libs/iostreams/doc/functions/tee.html). – 0x499602D2
Polecam zrobić to w środowisku wywołującym. –