At après les deux objets écrivent au même endroit ?
Oui exactement, pourquoi pas. N'est ce pas le comportement attendue
d'une redirection ? On fait bien cela en C en une seule instruction,
non ?
Oui, mais, par exemple, C n'a pas d'appel automatique au destructeur.
Donc, l'ambiguïté est laissée à la charge du programmeur.
Je cite cet aspect puisque c'est le seul que j'ai compris
sur le problème avec rdbuf, et je crois que tu as le même
dans la solution que tu trouvais 'élégante'.
At après les deux objets écrivent au même endroit ?
Oui exactement, pourquoi pas. N'est ce pas le comportement attendue
d'une redirection ? On fait bien cela en C en une seule instruction,
non ?
Oui, mais, par exemple, C n'a pas d'appel automatique au destructeur.
Donc, l'ambiguïté est laissée à la charge du programmeur.
Je cite cet aspect puisque c'est le seul que j'ai compris
sur le problème avec rdbuf, et je crois que tu as le même
dans la solution que tu trouvais 'élégante'.
At après les deux objets écrivent au même endroit ?
Oui exactement, pourquoi pas. N'est ce pas le comportement attendue
d'une redirection ? On fait bien cela en C en une seule instruction,
non ?
Oui, mais, par exemple, C n'a pas d'appel automatique au destructeur.
Donc, l'ambiguïté est laissée à la charge du programmeur.
Je cite cet aspect puisque c'est le seul que j'ai compris
sur le problème avec rdbuf, et je crois que tu as le même
dans la solution que tu trouvais 'élégante'.
Tout copier, ça veut dire quoi ? Il y a des états implicits,
par exemple ; un ofstream est propriétaire de son streambuf, et
le delete dans son constructeur.
ces questions, on se les pose à chaque fois qu'on surcharge un
opérateur d'affectation entre classes différentes. On arrive bien à
trouver une sémantique pour des cas plus compliqués que les flux
standards...
Dans la pratique, l'affectation ne marche pas pour des classes du
genre [io]stream. D'abord, parce que l'affectation ne marche pas bien
avec l'héritage ; tu affectes un ofstream à un ostream, et le
résultat est toujours un ostream, jamais un ofstream. (Les deux
objets ne sont donc pas égaux.)
Oui, en effet. Pour me reprendre, cette remarque est vraie dans un cas
plus général, i.e., entre les classes ascendantes et descendantes.
Je ne comprends pas pourquoi ce comité a rejeté cette
solution.
Parce que personne dans le comité a pû lui donner un sens.
Ou peut être qu'il y a eu plusieurs "sens" proposés mais aucun n'a
fait consensus chez les mandarins.
Il me paraît naturel, et peut être suffisant, de simplement proposer
le sens de l'affectation entre flux comme étant une redirection
classique.
Ensuite, l'implémentation est autre chose. Le thread que j'ai lancé a
proposé certaines pistes.
Je ne comprends pas. Ici, on fait quelque chose qui n'est même
pas possible en C. Et question de propreté et de lisabilité,
c'est quand même préférable de mettre la logique de décision
dans sa propre fonction, non ?
Je parlais de "ce cas précis", ie les redirections. En C, il est plus
facile de rediriger : on écrit : ofile=stdout; et voilà. Ensuite, il
faut faire attention aux bugs.
Tout copier, ça veut dire quoi ? Il y a des états implicits,
par exemple ; un ofstream est propriétaire de son streambuf, et
le delete dans son constructeur.
ces questions, on se les pose à chaque fois qu'on surcharge un
opérateur d'affectation entre classes différentes. On arrive bien à
trouver une sémantique pour des cas plus compliqués que les flux
standards...
Dans la pratique, l'affectation ne marche pas pour des classes du
genre [io]stream. D'abord, parce que l'affectation ne marche pas bien
avec l'héritage ; tu affectes un ofstream à un ostream, et le
résultat est toujours un ostream, jamais un ofstream. (Les deux
objets ne sont donc pas égaux.)
Oui, en effet. Pour me reprendre, cette remarque est vraie dans un cas
plus général, i.e., entre les classes ascendantes et descendantes.
Je ne comprends pas pourquoi ce comité a rejeté cette
solution.
Parce que personne dans le comité a pû lui donner un sens.
Ou peut être qu'il y a eu plusieurs "sens" proposés mais aucun n'a
fait consensus chez les mandarins.
Il me paraît naturel, et peut être suffisant, de simplement proposer
le sens de l'affectation entre flux comme étant une redirection
classique.
Ensuite, l'implémentation est autre chose. Le thread que j'ai lancé a
proposé certaines pistes.
Je ne comprends pas. Ici, on fait quelque chose qui n'est même
pas possible en C. Et question de propreté et de lisabilité,
c'est quand même préférable de mettre la logique de décision
dans sa propre fonction, non ?
Je parlais de "ce cas précis", ie les redirections. En C, il est plus
facile de rediriger : on écrit : ofile=stdout; et voilà. Ensuite, il
faut faire attention aux bugs.
Tout copier, ça veut dire quoi ? Il y a des états implicits,
par exemple ; un ofstream est propriétaire de son streambuf, et
le delete dans son constructeur.
ces questions, on se les pose à chaque fois qu'on surcharge un
opérateur d'affectation entre classes différentes. On arrive bien à
trouver une sémantique pour des cas plus compliqués que les flux
standards...
Dans la pratique, l'affectation ne marche pas pour des classes du
genre [io]stream. D'abord, parce que l'affectation ne marche pas bien
avec l'héritage ; tu affectes un ofstream à un ostream, et le
résultat est toujours un ostream, jamais un ofstream. (Les deux
objets ne sont donc pas égaux.)
Oui, en effet. Pour me reprendre, cette remarque est vraie dans un cas
plus général, i.e., entre les classes ascendantes et descendantes.
Je ne comprends pas pourquoi ce comité a rejeté cette
solution.
Parce que personne dans le comité a pû lui donner un sens.
Ou peut être qu'il y a eu plusieurs "sens" proposés mais aucun n'a
fait consensus chez les mandarins.
Il me paraît naturel, et peut être suffisant, de simplement proposer
le sens de l'affectation entre flux comme étant une redirection
classique.
Ensuite, l'implémentation est autre chose. Le thread que j'ai lancé a
proposé certaines pistes.
Je ne comprends pas. Ici, on fait quelque chose qui n'est même
pas possible en C. Et question de propreté et de lisabilité,
c'est quand même préférable de mettre la logique de décision
dans sa propre fonction, non ?
Je parlais de "ce cas précis", ie les redirections. En C, il est plus
facile de rediriger : on écrit : ofile=stdout; et voilà. Ensuite, il
faut faire attention aux bugs.
On Wed, 19 Jul 2006 10:51:46 +0200, Sid Touati :
En C, il est plus
facile de rediriger : on écrit : ofile=stdout; et voilà.
En C++, tu peux aussi utiliser les FILE*, si tu penses qu'ils sont
plus adaptés à ton problème.
On Wed, 19 Jul 2006 10:51:46 +0200, Sid Touati :
En C, il est plus
facile de rediriger : on écrit : ofile=stdout; et voilà.
En C++, tu peux aussi utiliser les FILE*, si tu penses qu'ils sont
plus adaptés à ton problème.
On Wed, 19 Jul 2006 10:51:46 +0200, Sid Touati :
En C, il est plus
facile de rediriger : on écrit : ofile=stdout; et voilà.
En C++, tu peux aussi utiliser les FILE*, si tu penses qu'ils sont
plus adaptés à ton problème.
Merci pour toutes les réactions intéressantes à ce thread. Mais j'ai
du mal à croire que l'approche orientée objet s'accommode mal avec les
redirections de flux.
Est ce uniquement une difficulté avec la librairie des streams C++ ?
Comment ferait-on en java ?
Je suis également surpris que tout le comité d'experts en C++ n'arrive
pas à trancher sur la sémantique de l'opérateur '=' sur les flux.
Si cela est causé par un véritable un problème de fond sur la
sémantique des objets streams, des équipes de recherche académique en
orienté objet ou en langages de flux seraient (par leur nature) plus
utiles qu'un comité.
Si c'est des problèmes techniques (de conception ou d'implémentation),
c'est autre chose. Les bons éléments trouvent toujours un moyen.
Je persiste à dire qu'une première définition de l'affectation de flux
en C++ est la redirection. (De mémoire, j'ai lu d'autres sémantiques
dans les langages de flux, mais ce n'est pas du C++).
Pour étayer un peu plus la définition de '=' : Si on écrit a=b, cela
équivaudrait par ex à ce que toute entrée/sortie sur a se fait sur le
buffer de b. Si b est fermé avant a,
cela se discute :
- On peut imaginer un cas particulier pour cout et cin (si je ne me
trompe pas, ces deux là ne ferment pas dans une application).
- On peut se débrouiller pour que a continue à être ouvert avec le
dernier état valide de b
- On peut dire que a devient inconsistant
- ....
Je fais confiance aux mandarins pour giberner sur ces points. Mais de
grâce, dire qu'on n'a pas de solution pour la définition de '=' sur
les streams C++ ...
Merci pour toutes les réactions intéressantes à ce thread. Mais j'ai
du mal à croire que l'approche orientée objet s'accommode mal avec les
redirections de flux.
Est ce uniquement une difficulté avec la librairie des streams C++ ?
Comment ferait-on en java ?
Je suis également surpris que tout le comité d'experts en C++ n'arrive
pas à trancher sur la sémantique de l'opérateur '=' sur les flux.
Si cela est causé par un véritable un problème de fond sur la
sémantique des objets streams, des équipes de recherche académique en
orienté objet ou en langages de flux seraient (par leur nature) plus
utiles qu'un comité.
Si c'est des problèmes techniques (de conception ou d'implémentation),
c'est autre chose. Les bons éléments trouvent toujours un moyen.
Je persiste à dire qu'une première définition de l'affectation de flux
en C++ est la redirection. (De mémoire, j'ai lu d'autres sémantiques
dans les langages de flux, mais ce n'est pas du C++).
Pour étayer un peu plus la définition de '=' : Si on écrit a=b, cela
équivaudrait par ex à ce que toute entrée/sortie sur a se fait sur le
buffer de b. Si b est fermé avant a,
cela se discute :
- On peut imaginer un cas particulier pour cout et cin (si je ne me
trompe pas, ces deux là ne ferment pas dans une application).
- On peut se débrouiller pour que a continue à être ouvert avec le
dernier état valide de b
- On peut dire que a devient inconsistant
- ....
Je fais confiance aux mandarins pour giberner sur ces points. Mais de
grâce, dire qu'on n'a pas de solution pour la définition de '=' sur
les streams C++ ...
Merci pour toutes les réactions intéressantes à ce thread. Mais j'ai
du mal à croire que l'approche orientée objet s'accommode mal avec les
redirections de flux.
Est ce uniquement une difficulté avec la librairie des streams C++ ?
Comment ferait-on en java ?
Je suis également surpris que tout le comité d'experts en C++ n'arrive
pas à trancher sur la sémantique de l'opérateur '=' sur les flux.
Si cela est causé par un véritable un problème de fond sur la
sémantique des objets streams, des équipes de recherche académique en
orienté objet ou en langages de flux seraient (par leur nature) plus
utiles qu'un comité.
Si c'est des problèmes techniques (de conception ou d'implémentation),
c'est autre chose. Les bons éléments trouvent toujours un moyen.
Je persiste à dire qu'une première définition de l'affectation de flux
en C++ est la redirection. (De mémoire, j'ai lu d'autres sémantiques
dans les langages de flux, mais ce n'est pas du C++).
Pour étayer un peu plus la définition de '=' : Si on écrit a=b, cela
équivaudrait par ex à ce que toute entrée/sortie sur a se fait sur le
buffer de b. Si b est fermé avant a,
cela se discute :
- On peut imaginer un cas particulier pour cout et cin (si je ne me
trompe pas, ces deux là ne ferment pas dans une application).
- On peut se débrouiller pour que a continue à être ouvert avec le
dernier état valide de b
- On peut dire que a devient inconsistant
- ....
Je fais confiance aux mandarins pour giberner sur ces points. Mais de
grâce, dire qu'on n'a pas de solution pour la définition de '=' sur
les streams C++ ...
oui.
// includes
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
oui.
// includes
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
oui.
// includes
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
oui.
// includes
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
J'ai fini par tester cette solution, hélas cela ne marche pas!
J'ai des comportements bizarres (sorties vers le mauvais
flux).
oui.
// includes
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
J'ai fini par tester cette solution, hélas cela ne marche pas!
J'ai des comportements bizarres (sorties vers le mauvais
flux).
oui.
// includes
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
J'ai fini par tester cette solution, hélas cela ne marche pas!
J'ai des comportements bizarres (sorties vers le mauvais
flux).
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
J'ai fini par tester cette solution, hélas cela ne marche pas! J'ai des
comportements bizarres (sorties vers le mauvais flux).
Je vais abandonner cette idée de redirection de flux sous C++ avec les
streams.
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
J'ai fini par tester cette solution, hélas cela ne marche pas! J'ai des
comportements bizarres (sorties vers le mauvais flux).
Je vais abandonner cette idée de redirection de flux sous C++ avec les
streams.
std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;
J'ai fini par tester cette solution, hélas cela ne marche pas! J'ai des
comportements bizarres (sorties vers le mauvais flux).
Je vais abandonner cette idée de redirection de flux sous C++ avec les
streams.
Aussi : quand tu dis « sorties » vers le mauvais flux,
s'agit-t-il d'une faute de frapper, ou est-ce que tu as changé
les types ci-dessus en std::ofstream, ou ? Et quand tu dis
« mauvais flux », est-ce que tu veux dire vers std::cout,
quand il aurait fallu vers le fichier, ou vers le fichier, quand
il aurait fallu vers std::cout, ou vers un autre fichier non
nommé. (Note bien que std::ofstream essaie de créer un fichier
s'il peut. Ce qui veut dire que cet idiome sert assez peu avec
les flux de sorties.)
--
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
Aussi : quand tu dis « sorties » vers le mauvais flux,
s'agit-t-il d'une faute de frapper, ou est-ce que tu as changé
les types ci-dessus en std::ofstream, ou ? Et quand tu dis
« mauvais flux », est-ce que tu veux dire vers std::cout,
quand il aurait fallu vers le fichier, ou vers le fichier, quand
il aurait fallu vers std::cout, ou vers un autre fichier non
nommé. (Note bien que std::ofstream essaie de créer un fichier
s'il peut. Ce qui veut dire que cet idiome sert assez peu avec
les flux de sorties.)
--
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
Aussi : quand tu dis « sorties » vers le mauvais flux,
s'agit-t-il d'une faute de frapper, ou est-ce que tu as changé
les types ci-dessus en std::ofstream, ou ? Et quand tu dis
« mauvais flux », est-ce que tu veux dire vers std::cout,
quand il aurait fallu vers le fichier, ou vers le fichier, quand
il aurait fallu vers std::cout, ou vers un autre fichier non
nommé. (Note bien que std::ofstream essaie de créer un fichier
s'il peut. Ce qui veut dire que cet idiome sert assez peu avec
les flux de sorties.)
--
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
Bonjour à tous,
j'ai cherché sur plusieurs documents et ouvrages de référence la
possibilité ou pas de programmer des redirections de flux localement à
une application C++. Je ne souhaite pas le faire via le shell, car de
telle redirections sont globales à toute l'application.
Bonjour à tous,
j'ai cherché sur plusieurs documents et ouvrages de référence la
possibilité ou pas de programmer des redirections de flux localement à
une application C++. Je ne souhaite pas le faire via le shell, car de
telle redirections sont globales à toute l'application.
Bonjour à tous,
j'ai cherché sur plusieurs documents et ouvrages de référence la
possibilité ou pas de programmer des redirections de flux localement à
une application C++. Je ne souhaite pas le faire via le shell, car de
telle redirections sont globales à toute l'application.
Je n'ai pas pris le temps de lire tout le fil mais il me semble
qu'aucune solution qui te convienne n'ait encore été proposée.
Moi j'utilise parfois celle-ci, peut-être pourra-t-elle t'aider :
#include <iostream>
#include <fstream>
#include <sstream>
class IOredirection
{
private:
std::streambuf* old_in;
std::streambuf* old_out;
std::streambuf* old_err;
std::streambuf* old_log;
public:
IOredirection(void)
{
old_out = std::cout.rdbuf();
old_err = std::cerr.rdbuf();
old_log = std::clog.rdbuf();
old_in = std::cin.rdbuf();
}
~IOredirection(void) { ResetStreams(); }
void setStdOut(std::ostream& out)
{ std::cout.rdbuf(out.rdbuf()); }
void setStdErr(std::ostream& err)
{ std::cerr.rdbuf(err.rdbuf()); }
void setStdLog(std::ostream& log)
{ std::clog.rdbuf(log.rdbuf()); }
void setStdIn(std::istream& in)
{ std::cin.rdbuf(in.rdbuf()); }
void ResetStreams(void)
{
std::cout.rdbuf(old_out);
std::cerr.rdbuf(old_err);
std::clog.rdbuf(old_log);
std::cin.rdbuf(old_in);
}
};
int main(int argc, char **argv)
{
IOredirection io;
std::ofstream out("out.txt"), err("err.txt"),
log("log.txt",std::ofstream::app);
io.setStdOut(out);
io.setStdErr(err);
io.setStdLog(log);
cout << "dans le fichier out.txt" << endl;
cerr << "dans le fichier err.txt" << endl;
clog << "dans le fichier log.txt" << endl;
//cin >> variable; // lecture depuis le fichier in.txt
}
Bien sûr il n'est pas nécessaire de tout rediriger.
Enfin pour bien faire les choses il faudrait faire de IOredirection un
singleton mais là ça fonctionne déjà bien, enfin si ça répond à tes
attentes.
Dernière remarque, si tu fais la redirection en cours de programme il
faut sans doute utiliser la version suivante pour garder tout l'état
des flux :
void setStdOut(std::ostream& out)
{
out.copyfmt(std::cout);
out.clear(std::cout.rdstate());
std::cout.rdbuf(out.rdbuf());
}
Je n'ai pas pris le temps de lire tout le fil mais il me semble
qu'aucune solution qui te convienne n'ait encore été proposée.
Moi j'utilise parfois celle-ci, peut-être pourra-t-elle t'aider :
#include <iostream>
#include <fstream>
#include <sstream>
class IOredirection
{
private:
std::streambuf* old_in;
std::streambuf* old_out;
std::streambuf* old_err;
std::streambuf* old_log;
public:
IOredirection(void)
{
old_out = std::cout.rdbuf();
old_err = std::cerr.rdbuf();
old_log = std::clog.rdbuf();
old_in = std::cin.rdbuf();
}
~IOredirection(void) { ResetStreams(); }
void setStdOut(std::ostream& out)
{ std::cout.rdbuf(out.rdbuf()); }
void setStdErr(std::ostream& err)
{ std::cerr.rdbuf(err.rdbuf()); }
void setStdLog(std::ostream& log)
{ std::clog.rdbuf(log.rdbuf()); }
void setStdIn(std::istream& in)
{ std::cin.rdbuf(in.rdbuf()); }
void ResetStreams(void)
{
std::cout.rdbuf(old_out);
std::cerr.rdbuf(old_err);
std::clog.rdbuf(old_log);
std::cin.rdbuf(old_in);
}
};
int main(int argc, char **argv)
{
IOredirection io;
std::ofstream out("out.txt"), err("err.txt"),
log("log.txt",std::ofstream::app);
io.setStdOut(out);
io.setStdErr(err);
io.setStdLog(log);
cout << "dans le fichier out.txt" << endl;
cerr << "dans le fichier err.txt" << endl;
clog << "dans le fichier log.txt" << endl;
//cin >> variable; // lecture depuis le fichier in.txt
}
Bien sûr il n'est pas nécessaire de tout rediriger.
Enfin pour bien faire les choses il faudrait faire de IOredirection un
singleton mais là ça fonctionne déjà bien, enfin si ça répond à tes
attentes.
Dernière remarque, si tu fais la redirection en cours de programme il
faut sans doute utiliser la version suivante pour garder tout l'état
des flux :
void setStdOut(std::ostream& out)
{
out.copyfmt(std::cout);
out.clear(std::cout.rdstate());
std::cout.rdbuf(out.rdbuf());
}
Je n'ai pas pris le temps de lire tout le fil mais il me semble
qu'aucune solution qui te convienne n'ait encore été proposée.
Moi j'utilise parfois celle-ci, peut-être pourra-t-elle t'aider :
#include <iostream>
#include <fstream>
#include <sstream>
class IOredirection
{
private:
std::streambuf* old_in;
std::streambuf* old_out;
std::streambuf* old_err;
std::streambuf* old_log;
public:
IOredirection(void)
{
old_out = std::cout.rdbuf();
old_err = std::cerr.rdbuf();
old_log = std::clog.rdbuf();
old_in = std::cin.rdbuf();
}
~IOredirection(void) { ResetStreams(); }
void setStdOut(std::ostream& out)
{ std::cout.rdbuf(out.rdbuf()); }
void setStdErr(std::ostream& err)
{ std::cerr.rdbuf(err.rdbuf()); }
void setStdLog(std::ostream& log)
{ std::clog.rdbuf(log.rdbuf()); }
void setStdIn(std::istream& in)
{ std::cin.rdbuf(in.rdbuf()); }
void ResetStreams(void)
{
std::cout.rdbuf(old_out);
std::cerr.rdbuf(old_err);
std::clog.rdbuf(old_log);
std::cin.rdbuf(old_in);
}
};
int main(int argc, char **argv)
{
IOredirection io;
std::ofstream out("out.txt"), err("err.txt"),
log("log.txt",std::ofstream::app);
io.setStdOut(out);
io.setStdErr(err);
io.setStdLog(log);
cout << "dans le fichier out.txt" << endl;
cerr << "dans le fichier err.txt" << endl;
clog << "dans le fichier log.txt" << endl;
//cin >> variable; // lecture depuis le fichier in.txt
}
Bien sûr il n'est pas nécessaire de tout rediriger.
Enfin pour bien faire les choses il faudrait faire de IOredirection un
singleton mais là ça fonctionne déjà bien, enfin si ça répond à tes
attentes.
Dernière remarque, si tu fais la redirection en cours de programme il
faut sans doute utiliser la version suivante pour garder tout l'état
des flux :
void setStdOut(std::ostream& out)
{
out.copyfmt(std::cout);
out.clear(std::cout.rdstate());
std::cout.rdbuf(out.rdbuf());
}