OVH Cloud OVH Cloud

[debutant] flux/fichier

24 réponses
Avatar
Bruno CAUSSE
Je lis dans la faq

bool is_readable( const std::string & file )
{
std::ifstream fichier( file.c_str() );
return fichier != 0;
}

Pourquoi on n'utilise pas return fichier.good() ?

Merci

4 réponses

1 2 3
Avatar
Andre Heinen
On Wed, 15 Jun 2005 09:50:58 -0400, "Michel Michaud"
wrote:

Dans le message ,
On Wed, 15 Jun 2005 03:59:00 -0400, "Michel Michaud"
wrote:
for(;;)
{
TypeDeX x;
flux >> x;
/***/
if (flux.fail()) break;
/***/
utilisation de x...
}

Je trouve le code plus clair ainsi


Je trouve justement que la boucle et demie explicite est moins
claire. L'idiome
while ( flux >> variable ) {
// utilisation de la variable
}
me paraît plus clairement faire la différence entre le code destiné
à initialiser la variable et celui qui l'utilise. AMHA.


Mais tu as oublié d'ajouter la déclaration de la variable :

TypeDeLaVariable variable;
while ( flux >> variable ) {
// utilisation de la variable
}

Moi je trouve que c'est maintenant moins clair que la valeur de
la variable est inutile après la boucle...


Et que penses-tu de ceci?

void f() {
blabla...
{
TypeDeLaVariable variable;
while ( flux >> variable ) {
// utilisation de la variable
}
}
blabla...
}

En fait, dans l'exemple que tu proposes, le code qui initialise la
variable et le code qui l'utilise sont clairement séparés aussi: par
le break. Mais je suis d'accord avec James: le break ne "ressort"
pas, et n'est facile à repérer.

--
André Heinen
Mon e-mail, encodé ROT13: n qbg urvara ng rhebcrnayvax qbg pbz
La FAQ: http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/



Avatar
kanze
Michel Michaud wrote:
Dans le message ,
"Michel Michaud" writes:
Dans mon esprit, il est vraiment dommage que des
programmeurs soient déroutées par des boucles et demie et
du code écrit explicitement :-)


Ce qui est deroutant (si quelque chose l'est) avec

for(;;)
{
TypeDeX x;
flux >> x;
/***/
if (flux.fail()) break;
/***/
utilisation de x...
}


c'est la non utilisation de la forme idiomatique.


Elle est idiomatique pour moi (et mes élèves et mes collègues,
etc.) :-)


Ce qui risque de leur poser des problèmes quand ils sortent de
l'école.

On s'habitue vite, mais j'avoue que j'aimerais mieux avoir une
instruction LOOP comme en Ada. Pendant un certain temps, je
faisais des #define pour avoir ce qu'il faut, mais ça m'a
passé...


Voilà qu'on commence à s'entendre. J'ai beau ne pas aimer les
boucles et demi comme ça, je trouverais quelque chose du genre :

LOOP
TypeDeX x ;
flux >> x ;
UNTIL flux.failed() ;
utilisation de x ...
END

assez acceptable. En supposant que LOOP, UNTIL et END était bien
des mots clé du langage, que tout le monde comprend. À une
époque, j'ai expérimenté avec quelque chose de ce genre, à
l'aide des macros. Il m'a plu assez, à moi, mais il posait des
problèmes à n'importe quel autre programmeur C (c'était à
l'époque où je faisais encore du C) qui le lisait. Parce que ce
n'est pas du C, tout simplement.

(Je ne sais pas s'il me plairait autant aujourd'hui. Depuis,
j'ai travaillé sur des programmes critique, où les exigences de
qualité et de robustesse était bien plus élevées. Et j'ai pû
constater que c'est beaucoup plus facile de raisonner sur une
boucle si les invariantes n'en changent pas en plein
milieu. Mais ben, tous les programmes ne gèrent pas des centraux
nucléaire, et ce n'est pas pire, à cet égard, qu'un do {...}
while. Qu'il m'arrive d'utiliser aussi, bien que rarement.)

On va chercher instinctivement la nuance pour s'apercevoir
qu'il n'y en a pas.


Il y a une nuance : la portée de x est limitée correctement.


C'est un avantage assez limité. C'est rare d'avoir une boucle,
et que ce n'est pas la dernière chose (voire la seule chose)
dans la fonction.

Je répète ce que j'ai souvent dit : si la fonction fait une
quarantaine de lignes, aved plusieurs niveaux d'embrication des
structures de contrôle de flux, elle est illisible. Quelque soit
la façon d'écrire les boucles et demi (ou d'autre chose). Et si
elle ne fait qu'une dizaine de lignes, avec au maximum une seule
embrication, on arrive très bien à la lire, même si elle ne
correspond à nos normes personnelles. Dans des limites,
évidemment -- s'il y trois goto, même les dix lignes risquent de
poser un problème. De même que si le code n'est pas écrit en
« C++ ».

En ce qui concerne les idiomes : personnellement, j'ai horreur
des lignes de code qui font plus d'une chose : qui modifie plus
d'une variable, ou qui modifie une variable *et* contrôle le
flux d'exécution. Donc, de quelque chose comme : « while ( flux
x ) ». Seulement, l'idiome est tellement omniprésent dans ce
cas-ci (au point que je n'ai jamais vu du code correct qui ne


s'en servait pas), que je m'y conforme. J'ai beau chercher des
alternatifs plus conforme à mes idées, je n'en trouve pas avec
lesquels mes collégues se sentent à l'aise.

La même chose vaut pour les portées des variables. Que je
déclare la variable immédiatement avant la boucle, ou comme la
première chose dans la boucle, ça ne change pas grand chose : la
fin de la boucle, c'est aussi la fin de la fonction. À peu près
la seule exception ici que je pourrais voir, c'est un
enchaînement des if :

if ( D1* p = dynamic_cast< D1* >( pBase ) ) {
// ...
} else if ( D2* p = dynamic_cast<< D2* >( pBase ) ) {
// ...
} else ...

Ici, il faudrait sinon autant de variables que des types à
tester, et pour peu que les noms se ressemblent (ce qui risque
fort d'être le cas), il y a risque qu'on se trompe de variable.
Alors, bien la forme me fait horreur -- avec non seulement la
modification, mais la déclaration d'une variable dans un
contrôle de flux, et en plus, une conversion implicite qui ne
doit même pas être dans le langage -- c'est idiomatique, et je
n'ai rien de mieux à proposer. (Heureusement, il y a rarement
besoin de ce genre de code.)

--
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
kanze
Andre Heinen wrote:
On Wed, 15 Jun 2005 09:50:58 -0400, "Michel Michaud"
wrote:

Dans le message ,

On Wed, 15 Jun 2005 03:59:00 -0400, "Michel Michaud"
wrote:
for(;;)
{
TypeDeX x;
flux >> x;
/***/
if (flux.fail()) break;
/***/
utilisation de x...
}

Je trouve le code plus clair ainsi


Je trouve justement que la boucle et demie explicite est
moins claire. L'idiome

while ( flux >> variable ) {
// utilisation de la variable
}

me paraît plus clairement faire la différence entre le code
destiné à initialiser la variable et celui qui l'utilise.
AMHA.


Mais tu as oublié d'ajouter la déclaration de la variable :

TypeDeLaVariable variable;
while ( flux >> variable ) {
// utilisation de la variable
}

Moi je trouve que c'est maintenant moins clair que la valeur
de la variable est inutile après la boucle...


Et que penses-tu de ceci?

void f() {
blabla...
{
TypeDeLaVariable variable;
while ( flux >> variable ) {
// utilisation de la variable
}
}
blabla...
}


Je verrais plutôt :

void lireLesDonnees( std::istream& flux )
{
TypeDeLaVariable variable ;
while ( flux >> variable ) {
// utilisation de la variable
}
}

void f()
{
blabla ...
lireLesDonnees( flux ) ;
blabla ...
}

Une bonne fonction ne fait qu'une seule chose.

--
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
Michel Michaud
Je ne veux pas relancer la discussion sur la boucle et demie,
surtout que j'ai lu la discussion sur SESE de clc++m... :-)

Mais, pour la forme et la postérité, je voulais simplement
ajouter quelque chose que j'ai déjà dit dans d'autres
discussions : mon intérêt premier pour la boucle et demie est
surtout l'idée qu'une boucle est du code qui se répète avec un
(seul) point de sortie, quelque part. Depuis que j'ai mis
l'emphase sur cette notion dans mon enseignement aux débutants,
j'ai beaucoup moins de difficultés avec leur apprentissage de
cette structure de contrôle. Je ne parle pas de boucle et demie,
je parle de boucle tout simplement. C'est peut-être difficile à
comprendre pour les programmeurs qui ont la moindre expérience,
mais ce n'est pas une notion facile pour les débutants moyens.

Au départ, mes élèves font des algorithmes avec du pseudo-code
qui ne différencie pas spécialement les types de boucle selon la
position de la sortie (mon pseudo-code ressemble à la boucle
unifiée de Ada). En C++, bien sûr, ils utilisent les while et
do-while quand c'est possible et le for(;;) avec if-break ailleurs.

Par contre, s'il venait à travailler quelque part où la boucle et
demie est « interdite » par un standard de programmation, je sais qu'ils
n'ont aucune difficulté à s'en passer. Lorsqu'on a un peu
d'expérience en programmation, c'est un petit détail. Vraiment
petit. Par ailleurs, curieusement, dans les programmes normaux,
contrairement aux programmes qu'on fait avec les débutants, il est
assez rare que la boucle et demie soit utile. Par contre, quand
elle l'est vraiment, je suis heureux de pouvoir la coder comme
telle et je crois bien que do-while est encore moins utile !

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
1 2 3