Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Dupliquer une sortie

6 réponses
Avatar
Lucas Levrel
Bonjour,

Y a-t-il un moyen simple de créer un objet qui s'utilise comme un ostream
et qui écrive en même temps dans un fichier et dans la sortie standard ?
(L'équivalent de la commande unix tee.)

Merci.

--
LL

6 réponses

Avatar
Michael Doubez
On 13 avr, 11:25, Lucas Levrel wrote:
Y a-t-il un moyen simple de créer un objet qui s'utilise comme un ostre am
et qui écrive en même temps dans un fichier et dans la sortie standar d ?
(L'équivalent de la commande unix tee.)



Oui

Le prototype est du genre:

class TeeStream
{
public:
TeeStream( std::ostream& dest1 , std::ostream& dest2)
: out1(&dest1), out2(&dest2)
{}

std::ostream& stream1() const { return *out1;}
std::ostream& stream2() const { return *out2;}

private:
std::ostream* out1;
std::ostream* out2;
} ;

template< typename T >
TeeStream const&
operator<<( TeeStream const& dest, T const& obj )
{
dest.stream1()<<obj;
dest.stream2()<<obj;
}

TeeStream const&
operator<<( TeeStream const& dest
, std::ios_base& (* manip)( std::ios_base& ) )
{
dest.stream1()<<manip;
dest.stream2()<<manip;
}

TeeStream const&
operator<<( TeeStream const& dest
, std::ostream& (*manip)( std::ostream& ) )
{
dest.stream1()<<manip;
dest.stream2()<<manip;
}

Mais je pense qu'il serait plus facile de faire un streambuf qui
duplique la sortie, comme ça tu n'aura qu'une seule fois le formatage
et tu garderais un std::ostream en interface.

--
Michael
Avatar
Lucas Levrel
Le 13 avril 2010, Michael Doubez a écrit :

On 13 avr, 11:25, Lucas Levrel wrote:
Y a-t-il un moyen simple de créer un objet qui s'utilise comme un ostream
et qui écrive en même temps dans un fichier et dans la sortie standard ?
(L'équivalent de la commande unix tee.)



Oui

Le prototype est du genre:



Merci !

Mais je pense qu'il serait plus facile de faire un streambuf qui



facile <--> efficace ?

duplique la sortie, comme ça tu n'aura qu'une seule fois le formatage
et tu garderais un std::ostream en interface.



Tu veux dire créer une classe dérivée de streambuf qu'on utiliserait dans
le constructeur d'un ostream ? (cf
http://www.cplusplus.com/reference/iostream/ostream/ostream/)

Quand je vois le header de filebuf, ça me paraît bien au-delà de mon
niveau. Par ailleurs je n'ai pas trouvé de header qui définisse cout en
terme de streambuf.

--
LL
Avatar
James Kanze
On Apr 14, 10:50 am, Lucas Levrel
wrote:
Le 13 avril 2010, Michael Doubez a écrit :



[...]
> Mais je pense qu'il serait plus facile de faire un streambuf qui

facile <--> efficace ?



Les deux. Dans la pratique, les streambuf filtrant, c'est quand
même un concepte connu, dont on trouverait les implémentations
chez Boost ou sur ma site. Et avec un streambuf filtrant, les
clients ne voient toujours qu'un ostream, et non un TeeStream
qui n'a rien à voir.

> duplique la sortie, comme ça tu n'aura qu'une seule fois le
> formatage et tu garderais un std::ostream en interface.

Tu veux dire créer une classe dérivée de streambuf qu'on
utiliserait dans le constructeur d'un ostream ?
(cfhttp://www.cplusplus.com/reference/iostream/ostream/ostream/)

Quand je vois le header de filebuf, ça me paraît bien au-delà
de mon niveau. Par ailleurs je n'ai pas trouvé de header qui
définisse cout en terme de streambuf.



Pour le streambuf, voir:
http://kanze.james.neuf.fr/articles/fltrsbf1.html. Il doit y
avoir du code tout fait chez Boost aussi. Quant à std::cout, il
y a toujours le version non-const de rdbuf.

--
James Kanze
Avatar
Michael Doubez
On 14 avr, 11:50, Lucas Levrel wrote:
Le 13 avril 2010, Michael Doubez a écrit :

> On 13 avr, 11:25, Lucas Levrel wrote:
>> Y a-t-il un moyen simple de créer un objet qui s'utilise comme un os tream
>> et qui écrive en même temps dans un fichier et dans la sortie stan dard ?
>> (L'équivalent de la commande unix tee.)

> Oui

> Le prototype est du genre:

Merci !

> Mais je pense qu'il serait plus facile de faire un streambuf  qui

facile <--> efficace ?

> duplique la sortie, comme ça tu n'aura qu'une seule fois le formatage
> et tu garderais un std::ostream en interface.

Tu veux dire créer une classe dérivée de streambuf qu'on utiliserai t dans
le constructeur d'un ostream ? (cfhttp://www.cplusplus.com/reference/iost ream/ostream/ostream/)



Je veux dire une class dérivée de streambuf qui revoit les données
dans des streambuf composé. Le streambuf d'une stream peut être obtenu
par rdbuf().


Quand je vois le header de filebuf, ça me paraît bien au-delà de mo n
niveau.



Tu n'as pas besoin de tout réimplémenter.

Une implementation minimal est du type:

class TeeStreambuf: public std::streambuf
{
// interface un peu comme TeeStream

protected: // redefini les fonctions de sortie:
std::streamsize xsputn ( const char * s, streamsize n )
{
return std::min(out1->xsputn(s,n),out2->xsputn(s,n) );
}
int overflow ( int c )
{
return out1->overflow(c) == EOF || out2->overflow(c) == EOF
? EOF
: 0
;
}
private:
std::streambuf* out1;
std::streambuf* out2;
};

Par ailleurs je n'ai pas trouvé de header qui définisse cout en
terme de streambuf.



Utilise std::ostream::rdbuf()

--
Michael
Avatar
Lucas Levrel
Le 14 avril 2010, James Kanze a écrit :

On Apr 14, 10:50 am, Lucas Levrel
wrote:

facile <--> efficace ?



Les deux. Dans la pratique, les streambuf filtrant, c'est quand
même un concepte connu,



« Judging from questions on the network, this is a little known area of
C++, so I cannot suppose knowledge of even the basic principles. »

:-D

Et avec un streambuf filtrant, les clients ne voient toujours qu'un
ostream, et non un TeeStream qui n'a rien à voir.



J'avais bien compris l'intérêt, ma difficulté étant de savoir
l'implémenter.

Pour le streambuf, voir:
http://kanze.james.neuf.fr/articles/fltrsbf1.html.



Merci !

--
LL
Avatar
Lucas Levrel
Le 15 avril 2010, Michael Doubez a écrit :

Tu n'as pas besoin de tout réimplémenter.

Une implementation minimal est du type:



Merci !

--
LL