Dupliquer une sortie

Le
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
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Michael Doubez
Le #21547241
On 13 avr, 11:25, Lucas Levrel
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
Lucas Levrel
Le #21553331
Le 13 avril 2010, Michael Doubez a écrit :

On 13 avr, 11:25, Lucas Levrel
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
James Kanze
Le #21558291
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
Michael Doubez
Le #21559621
On 14 avr, 11:50, Lucas Levrel
Le 13 avril 2010, Michael Doubez a écrit :

> On 13 avr, 11:25, Lucas Levrel >> 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
Lucas Levrel
Le #21562041
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
Lucas Levrel
Le #21562031
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
Publicité
Poster une réponse
Anonyme