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

redirection de flux dans une application C++

47 réponses
Avatar
Sid Touati
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.

Je remercie d'avance tout gourou de C++.

S

10 réponses

1 2 3 4 5
Avatar
Marc Boyer
Le 17-07-2006, Sid Touati a écrit :
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.


J'ai déjà eut un problème similaire, et cela a donné la
discussion suivante:
cout ou un fichier...


Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)

Avatar
Sid Touati

J'ai déjà eut un problème similaire, et cela a donné la
discussion suivante:
cout ou un fichier...


Marc Boyer


Merci d'avoir tenté de répondre, hélas je n'arrive pas à accéder à cette
archive (erreur de post ?) :



J'ai recherché avec google dans les threads de Marc Boyer dans ce
newsgroupe, ce sujet ne semble pas être traité à première vu.

S

Avatar
Marc Boyer
Le 17-07-2006, Sid Touati a écrit :

J'ai déjà eut un problème similaire, et cela a donné la
discussion suivante:
cout ou un fichier...


Marc Boyer


Merci d'avoir tenté de répondre, hélas je n'arrive pas à accéder à cette
archive (erreur de post ?) :



J'ai recherché avec google dans les threads de Marc Boyer dans ce
newsgroupe, ce sujet ne semble pas être traité à première vu.


Ben, j'ai tapé

dans Google, et il m'a trouvé le thread du premier coup.

http://groups.google.fr/group/fr.comp.lang.c++/browse_frm/thread/13cd3e894cd50ea5/428ed3e7aae2a4cf?lnk=st&q=slrndupgcg.hpv.Marc.Boyer%40localhost.localdomain&rnum=2&hl=fr#428ed3e7aae2a4cf


--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)


Avatar
Sid Touati
Ben, j'ai tapé

dans Google, et il m'a trouvé le thread du premier coup.

http://groups.google.fr/group/fr.comp.lang.c++/browse_frm/thread/13cd3e894cd50ea5/428ed3e7aae2a4cf?lnk=st&q=slrndupgcg.hpv.Marc.Boyer%40localhost.localdomain&rnum=2&hl=fr#428ed3e7aae2a4cf



Exact. Merci pour la référence. En C c'était plus facile en effet.
On pourrait peut être penser à surcharger l'opérateur d'affectation '='
entre les différents flux afin de faciliter les redirections, non ?

S

Avatar
Marc Boyer
Le 17-07-2006, Sid Touati a écrit :
Ben, j'ai tapé

dans Google, et il m'a trouvé le thread du premier coup.

http://groups.google.fr/group/fr.comp.lang.c++/browse_frm/thread/13cd3e894cd50ea5/428ed3e7aae2a4cf?lnk=st&q=slrndupgcg.hpv.Marc.Boyer%40localhost.localdomain&rnum=2&hl=fr#428ed3e7aae2a4cf



Exact. Merci pour la référence. En C c'était plus facile en effet.


En effet.
*
On pourrait peut être penser à surcharger l'opérateur d'affectation '='
entre les différents flux afin de faciliter les redirections, non ?


Je suis bien trop nul sur cette partie de C++ pour avoir
un quelconque avis sur les problèmes que cela poserait.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)


Avatar
Manuel Zaccaria
"Sid Touati" a écrit:
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")


Le nom "ofile" est mal choisi. Pour moi, il évoque une sortie.
Je verrais plutôt "ifile" ici.

[snip]
Est-ce possible de faire cela ?


oui.

// includes

std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;

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&".


Manuel

Avatar
Sid Touati
oui.

// includes

std::ifstream ifile("Toto.txt");
std::istream& input = ifile ? static_cast<std::istream&>(ifile) : cin;

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&".


Manuel


Bravo, cette solution me paraît plus élégante et plus compacte. Je la

teste...
Merci

S

Avatar
kanze
Sid Touati wrote:
Ben, j'ai tapé

dans Google, et il m'a trouvé le thread du premier coup.

http://groups.google.fr/group/fr.comp.lang.c++/browse_frm/thread/13cd3e 894cd50ea5/428ed3e7aae2a4cf?lnk=st&q=slrndupgcg.hpv.Marc.Boyer%40localh ost.localdomain&rnum=2&hl=fr#428ed3e7aae2a4cf


Exact. Merci pour la référence. En C c'était plus facile en
effet. On pourrait peut être penser à surcharger l'opérateur
d'affectation '=' entre les différents flux afin de faciliter
les redirections, non ?


Ça a été rejeté par le comité, exprès. Ça veut dire quoi,
l'affectation d'un flux ? Copie des états d'erreur ? Copie des
options de formattage ? Le comité a finalement décidé de le
découper la fonctionalité en plusieurs fonctions, chacune avec
un nom parlant.

En général, je n'aime pas l'idée de jouer trop avec la version
non-const de rdbuf() ; on arrive très vite à des cas plutôt
bizarre. Dans ton cas, par exemple, je ferais quelque chose
plutôt du genre :

streambuf*
getStreambuf( std::string const& filename )
{
std::auto_ptr< std::streambuf >
file( std::new filebuf ) ;
return file->open( filename.c_str(), std::in )
? file.release()
: std::cin.rdbuf() ;
}

et ensuite :

std::istream input( getStreambuf( filename ) ) ;
// ...
if ( input.rdbuf() != std::cin.rdbuf() ) {
delete input.rdbuf() ;
}

(En fait, j'utiliserais sans doute une classe RAII pour la
gestion du streambuf*. Histoire de ne pas rater le delete en cas
d'exception.)

--
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


Avatar
Sid Touati

Ça a été rejeté par le comité, exprès. Ça veut dire quoi,
l'affectation d'un flux ? Copie des états d'erreur ? Copie des
options de formattage ?


Heu ... je pense que tout copier ferait bien l'affaire, d'autant plus
que c'est le comportement attendu pour un opérateur d'affectation '='.
Je ne comprends pas pourquoi ce comité a rejeté cette solution.

streambuf*
getStreambuf( std::string const& filename )
{
std::auto_ptr< std::streambuf >
file( std::new filebuf ) ;
return file->open( filename.c_str(), std::in )
? file.release()
: std::cin.rdbuf() ;
}

et ensuite :

std::istream input( getStreambuf( filename ) ) ;
// ...
if ( input.rdbuf() != std::cin.rdbuf() ) {
delete input.rdbuf() ;
}


Disons que... d'habitude en C++, une ligne de code vaut plusieurs lignes
en C. Dans ce cas précis, une ligne en C vaut plusieurs en C++. Cela
n'est pas top. On a l'impression d'utiliser un canon pour abattre une
mouche : aller si loin dans le C++ rien que pour redirriger un flux, y a
de quoi démotiver.

Heureusement, Manuel Zaccaria donne une solution qui semble plus
compacte. Je ne l'ai pas encore testé.

S

Avatar
Gabriel Dos Reis
Sid Touati writes:

| > Ça a été rejeté par le comité, exprès. Ça veut dire quoi,
| > l'affectation d'un flux ? Copie des états d'erreur ? Copie des
| > options de formattage ?
|
| Heu ... je pense que tout copier ferait bien l'affaire, d'autant plus
| que c'est le comportement attendu pour un opérateur d'affectation '='.

At après les deux objets écrivent au même endroit ?

| 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.

| > streambuf*
| > getStreambuf( std::string const& filename )
| > {
| > std::auto_ptr< std::streambuf >
| > file( std::new filebuf ) ;
| > return file->open( filename.c_str(), std::in )
| > ? file.release()
| > : std::cin.rdbuf() ;
| > }
| > et ensuite :
| > std::istream input( getStreambuf( filename ) ) ;
| > // ...
| > if ( input.rdbuf() != std::cin.rdbuf() ) {
| > delete input.rdbuf() ;
| > }
|
| Disons que... d'habitude en C++, une ligne de code vaut plusieurs
| lignes en C. Dans ce cas précis, une ligne en C vaut plusieurs en
| C++. Cela n'est pas top. On a l'impression d'utiliser un canon pour
| abattre une mouche : aller si loin dans le C++ rien que pour
| redirriger un flux, y a de quoi démotiver.

La question est de savoir si ces deux « solutiones » s'adressent au
même problème. Probablement que non. Alors, comparer banane à orange...

-- Gaby
1 2 3 4 5