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 veux faire quelque chose du genre :
ifstream ofile("Toto.txt")
if (!ofile) {
cerr<<"Zut. Pas pu ouvrir. Je lis à partir de stdin à partir de
maintenant.\n";
// ofile=cin ; <===== Je veux implémenter cela. A savoir que
ofile devienne un alias de cin
}
Est-ce possible de faire cela ?
Je sais qu'on peut toujours remplacer ofile par cin dans le reste de
l'application, mais je préfère d'abord voir si on peut aliaser cin avec
un autre ifstream. Cela simplifierait le code.
Utilisez "input" à la place de "ifile". Si possible, il est préférable de manipuler les flux en termes de "std::istream&" et "std::ostream&".
Bravo, cette solution me paraît plus élégante et plus compacte. Je la teste...
Ce n'est pas vraiment une 'solution' comme c'est écrit.
Bien sûr que si. C'est même LA solution pour le problème exactement comme on l'a posé, et c'est sans doute ce que je ferais moi-même dans cet exact cas. La solution que j'ai postée cherchait à être plus générique (s'adapter facilement à d'autres variants du problème), et surtout plus pédégogique (donner un petit aperçu du rôle des streambuf -- cette séparation de concernes est en fait un outil extrèmement puissant une fois qu'on le connaît).
Comme disait Gaby, comparer les deux solutions, c'est comme comparer des bananes et des oranges. (J'aurais dit des pommes et des oranges. Je ne sais pas si c'est simplement un anglicisme qui est resté dans mon français, ou si c'est parce qu'on a grandi à des latitudes différentes.)
Gabriel Dos Reis et Pierre Barbier de Reuille ont raison mais je voulais surtout porter l'attention sur les classes istream et ostream sans avoir à rediriger les flux standard cin et cout. La variable input ne devrait même pas être là. J'aurais mieux fait d'écrire:
void Lecture(std::istream& input) { // utilise input (ici pas de souci de durée de vie de ifile vs inpu t) }
et utiliser avec ifile ou cin.
Tout à fait, et ça vaut la peine d'être dit. La création (et le choix) du « istream » est prèsque toujours séparée de son utilisation.
L'avantage de rediriger cin et/ou cout est que ça évite de modifier tout le code mais c'est pas une panacée non plus (on n'a qu'un fichier de chaque). L'avantage d'utiliser istream et/ou ostream (dans du nouveau code) est que, à mon avis, c'est plus souple à utiliser. Mais je ne suis pas un expert.
À peu près la seule des « objets » des flux qu'on utiliserait directement, c'est std::cerr, et encore, seulement dans des programmes les plus simples. Comme tu dis, les entrées/sorties s'effectuent sur des istream& et des ostream&, qui ont été initialisés ailleurs -- chez moi, au moins, ce sont prèsque toujours (plus que 99%) des paramètres d'une fonction. Ce qui n'empèche pas que dans tous sauf les cas les plus simples, la logique du choix de fichier se trouvent aussi dans une fonction à part.
-- 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
Utilisez "input" à la place de "ifile". Si possible, il est
préférable de manipuler les flux en termes de
"std::istream&" et "std::ostream&".
Bravo, cette solution me paraît plus élégante et plus
compacte. Je la teste...
Ce n'est pas vraiment une 'solution' comme c'est écrit.
Bien sûr que si. C'est même LA solution pour le problème
exactement comme on l'a posé, et c'est sans doute ce que je
ferais moi-même dans cet exact cas. La solution que j'ai postée
cherchait à être plus générique (s'adapter facilement à d'autres
variants du problème), et surtout plus pédégogique (donner un
petit aperçu du rôle des streambuf -- cette séparation de
concernes est en fait un outil extrèmement puissant une fois
qu'on le connaît).
Comme disait Gaby, comparer les deux solutions, c'est comme
comparer des bananes et des oranges. (J'aurais dit des pommes et
des oranges. Je ne sais pas si c'est simplement un anglicisme
qui est resté dans mon français, ou si c'est parce qu'on a
grandi à des latitudes différentes.)
Gabriel Dos Reis et Pierre Barbier de Reuille ont raison mais
je voulais surtout porter l'attention sur les classes istream
et ostream sans avoir à rediriger les flux standard cin et
cout. La variable input ne devrait même pas être là. J'aurais
mieux fait d'écrire:
void Lecture(std::istream& input)
{
// utilise input (ici pas de souci de durée de vie de ifile vs inpu t)
}
et utiliser avec ifile ou cin.
Tout à fait, et ça vaut la peine d'être dit. La création (et le
choix) du « istream » est prèsque toujours séparée de son
utilisation.
L'avantage de rediriger cin et/ou cout est que ça évite de
modifier tout le code mais c'est pas une panacée non plus (on
n'a qu'un fichier de chaque). L'avantage d'utiliser istream
et/ou ostream (dans du nouveau code) est que, à mon avis,
c'est plus souple à utiliser. Mais je ne suis pas un expert.
À peu près la seule des « objets » des flux qu'on utiliserait
directement, c'est std::cerr, et encore, seulement dans des
programmes les plus simples. Comme tu dis, les entrées/sorties
s'effectuent sur des istream& et des ostream&, qui ont été
initialisés ailleurs -- chez moi, au moins, ce sont prèsque
toujours (plus que 99%) des paramètres d'une fonction. Ce qui
n'empèche pas que dans tous sauf les cas les plus simples, la
logique du choix de fichier se trouvent aussi dans une fonction
à part.
--
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
Utilisez "input" à la place de "ifile". Si possible, il est préférable de manipuler les flux en termes de "std::istream&" et "std::ostream&".
Bravo, cette solution me paraît plus élégante et plus compacte. Je la teste...
Ce n'est pas vraiment une 'solution' comme c'est écrit.
Bien sûr que si. C'est même LA solution pour le problème exactement comme on l'a posé, et c'est sans doute ce que je ferais moi-même dans cet exact cas. La solution que j'ai postée cherchait à être plus générique (s'adapter facilement à d'autres variants du problème), et surtout plus pédégogique (donner un petit aperçu du rôle des streambuf -- cette séparation de concernes est en fait un outil extrèmement puissant une fois qu'on le connaît).
Comme disait Gaby, comparer les deux solutions, c'est comme comparer des bananes et des oranges. (J'aurais dit des pommes et des oranges. Je ne sais pas si c'est simplement un anglicisme qui est resté dans mon français, ou si c'est parce qu'on a grandi à des latitudes différentes.)
Gabriel Dos Reis et Pierre Barbier de Reuille ont raison mais je voulais surtout porter l'attention sur les classes istream et ostream sans avoir à rediriger les flux standard cin et cout. La variable input ne devrait même pas être là. J'aurais mieux fait d'écrire:
void Lecture(std::istream& input) { // utilise input (ici pas de souci de durée de vie de ifile vs inpu t) }
et utiliser avec ifile ou cin.
Tout à fait, et ça vaut la peine d'être dit. La création (et le choix) du « istream » est prèsque toujours séparée de son utilisation.
L'avantage de rediriger cin et/ou cout est que ça évite de modifier tout le code mais c'est pas une panacée non plus (on n'a qu'un fichier de chaque). L'avantage d'utiliser istream et/ou ostream (dans du nouveau code) est que, à mon avis, c'est plus souple à utiliser. Mais je ne suis pas un expert.
À peu près la seule des « objets » des flux qu'on utiliserait directement, c'est std::cerr, et encore, seulement dans des programmes les plus simples. Comme tu dis, les entrées/sorties s'effectuent sur des istream& et des ostream&, qui ont été initialisés ailleurs -- chez moi, au moins, ce sont prèsque toujours (plus que 99%) des paramètres d'une fonction. Ce qui n'empèche pas que dans tous sauf les cas les plus simples, la logique du choix de fichier se trouvent aussi dans une fonction à part.
-- 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
Sid Touati
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++ ...
S
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++ ...
S
Gabriel Dos Reis
"kanze" writes:
[...]
| Comme disait Gaby, comparer les deux solutions, c'est comme | comparer des bananes et des oranges. (J'aurais dit des pommes et | des oranges. Je ne sais pas si c'est simplement un anglicisme | qui est resté dans mon français, ou si c'est parce qu'on a | grandi à des latitudes différentes.)
J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange pas ici (ni en Europe d'ailleurs).
-- Gaby
"kanze" <kanze@gabi-soft.fr> writes:
[...]
| Comme disait Gaby, comparer les deux solutions, c'est comme
| comparer des bananes et des oranges. (J'aurais dit des pommes et
| des oranges. Je ne sais pas si c'est simplement un anglicisme
| qui est resté dans mon français, ou si c'est parce qu'on a
| grandi à des latitudes différentes.)
J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange
pas ici (ni en Europe d'ailleurs).
| Comme disait Gaby, comparer les deux solutions, c'est comme | comparer des bananes et des oranges. (J'aurais dit des pommes et | des oranges. Je ne sais pas si c'est simplement un anglicisme | qui est resté dans mon français, ou si c'est parce qu'on a | grandi à des latitudes différentes.)
J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange pas ici (ni en Europe d'ailleurs).
-- Gaby
Gabriel Dos Reis
Sid Touati writes:
[...]
| 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.
Il y a des problèmes bien plus importants à résoudre.
[...]
| 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++ ...
Le problème n'est pas qu'il n'y a pas de solutions. Il y a trop de solutions incomplètes. Si tu ne peux pas comprendre cela...
| 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.
Il y a des problèmes bien plus importants à résoudre.
[...]
| 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++ ...
Le problème n'est pas qu'il n'y a pas de solutions. Il y a trop de
solutions incomplètes. Si tu ne peux pas comprendre cela...
| 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.
Il y a des problèmes bien plus importants à résoudre.
[...]
| 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++ ...
Le problème n'est pas qu'il n'y a pas de solutions. Il y a trop de solutions incomplètes. Si tu ne peux pas comprendre cela...
-- Gaby
Sid Touati
J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange pas ici (ni en Europe d'ailleurs).
Pour ta gouvernance, puis-je suggérer des carottes, cela rend plus aimable parait-il.
S
J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange
pas ici (ni en Europe d'ailleurs).
Pour ta gouvernance, puis-je suggérer des carottes, cela rend plus
aimable parait-il.
puis-je suggérer des carottes, cela rend plus aimable parait-il.
As-tu déjà eu une conversation avec un lapin, pour pouvoir t'en rendre compte ?
Fabien LE LEZ
On Thu, 20 Jul 2006 10:45:20 +0200, Sid Touati :
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.
Il y a beaucoup de classes pour lesquelles tel ou tel opérateur n'a pas un sens évident. Pour ces classes, définir l'opérateur en question serait de l'obfuscation.
On Thu, 20 Jul 2006 10:45:20 +0200, Sid Touati :
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.
Il y a beaucoup de classes pour lesquelles tel ou tel opérateur n'a
pas un sens évident. Pour ces classes, définir l'opérateur en question
serait de l'obfuscation.
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.
Il y a beaucoup de classes pour lesquelles tel ou tel opérateur n'a pas un sens évident. Pour ces classes, définir l'opérateur en question serait de l'obfuscation.
Gabriel Dos Reis
Sid Touati writes:
| > J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange | > pas ici (ni en Europe d'ailleurs). | | Pour ta gouvernance, puis-je suggérer des carottes,
| > J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange
| > pas ici (ni en Europe d'ailleurs).
|
| Pour ta gouvernance, puis-je suggérer des carottes,
| > J'ai mis « bananes » pour varier un peu -- surtout que je n'en mange | > pas ici (ni en Europe d'ailleurs). | | Pour ta gouvernance, puis-je suggérer des carottes,
Déjà fait.
-- Gaby
James Kanze
Sid Touati wrote:
At après les deux objets écrivent au même endroit ?
Oui exactement, pourquoi pas.
Parce qu'on ne sait pas le faire dans tous les cas. Le problème (parmi d'autres), c'est qu'après l'affectation, on ne sait pas où écrira le deuxième après on a écrit avec le premier flux.
Un flux a une identité. Conceptuellement, donc, pas d'affectation. (Vue la façon que la durée de vie est gérer par des classes dérivées, je ne suis même pas sûr que la version non-const de rdbuf soit une bonne idée.)
N'est ce pas le comportement attendue d'une redirection ? On fait bien cela en C en une seule instruction, non ?
Non. En C non plus, un FILE ne peut pas être affecté.
La différence, c'est qu'en C, en général, on travaille avec des FILE*. Mais rien n'empêche de faire pareil en C++ avec des flux c'est indirectement á la base de la solution de Manuel.
| Je ne comprends pas pourquoi ce comité a rejeté cette solution.
Probablement sur la base de longues années d'expérience avec cette histoire de copie de flux.
Parfait, mais cela ne réponds pas à la question : pourquoi la copie de flux n'est elle pas une solution retenue ? Dire que les sages et les mandarins l'ont décidé pour le bienfait du C++, c'est un peu limite.
Parce qu'on n'a pas réussi à en trouver une définition qui convient dans tous les cas. Dire « copie », c'est toujours ne rien dire : copier quoi ? Qu'est-ce qui se passe si j'affecte un ofstream à un ostringstream, par exemple ?
-- James Kanze 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
Sid Touati wrote:
At après les deux objets écrivent au même endroit ?
Oui exactement, pourquoi pas.
Parce qu'on ne sait pas le faire dans tous les cas. Le problème (parmi
d'autres), c'est qu'après l'affectation, on ne sait pas où écrira le
deuxième après on a écrit avec le premier flux.
Un flux a une identité. Conceptuellement, donc, pas d'affectation. (Vue
la façon que la durée de vie est gérer par des classes dérivées, je ne
suis même pas sûr que la version non-const de rdbuf soit une bonne
idée.)
N'est ce pas le comportement attendue d'une redirection ? On fait bien
cela en C en une seule instruction, non ?
Non. En C non plus, un FILE ne peut pas être affecté.
La différence, c'est qu'en C, en général, on travaille avec des FILE*.
Mais rien n'empêche de faire pareil en C++ avec des flux c'est
indirectement á la base de la solution de Manuel.
| Je ne comprends pas pourquoi ce comité a rejeté cette solution.
Probablement sur la base de longues années d'expérience avec cette
histoire de copie de flux.
Parfait, mais cela ne réponds pas à la question : pourquoi la copie de
flux n'est elle pas une solution retenue ? Dire que les sages et les
mandarins l'ont décidé pour le bienfait du C++, c'est un peu limite.
Parce qu'on n'a pas réussi à en trouver une définition qui convient dans
tous les cas. Dire « copie », c'est toujours ne rien dire : copier
quoi ? Qu'est-ce qui se passe si j'affecte un ofstream à un
ostringstream, par exemple ?
--
James Kanze kanze.james@neuf.fr
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
At après les deux objets écrivent au même endroit ?
Oui exactement, pourquoi pas.
Parce qu'on ne sait pas le faire dans tous les cas. Le problème (parmi d'autres), c'est qu'après l'affectation, on ne sait pas où écrira le deuxième après on a écrit avec le premier flux.
Un flux a une identité. Conceptuellement, donc, pas d'affectation. (Vue la façon que la durée de vie est gérer par des classes dérivées, je ne suis même pas sûr que la version non-const de rdbuf soit une bonne idée.)
N'est ce pas le comportement attendue d'une redirection ? On fait bien cela en C en une seule instruction, non ?
Non. En C non plus, un FILE ne peut pas être affecté.
La différence, c'est qu'en C, en général, on travaille avec des FILE*. Mais rien n'empêche de faire pareil en C++ avec des flux c'est indirectement á la base de la solution de Manuel.
| Je ne comprends pas pourquoi ce comité a rejeté cette solution.
Probablement sur la base de longues années d'expérience avec cette histoire de copie de flux.
Parfait, mais cela ne réponds pas à la question : pourquoi la copie de flux n'est elle pas une solution retenue ? Dire que les sages et les mandarins l'ont décidé pour le bienfait du C++, c'est un peu limite.
Parce qu'on n'a pas réussi à en trouver une définition qui convient dans tous les cas. Dire « copie », c'est toujours ne rien dire : copier quoi ? Qu'est-ce qui se passe si j'affecte un ofstream à un ostringstream, par exemple ?
-- James Kanze 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