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

10 réponses

1 2 3
Avatar
Jean-Marc Bourguet
"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. On va chercher
instinctivement la nuance pour s'apercevoir qu'il n'y en a pas.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

| Ça démontre une crainte de coder une vraie boucle et
| demie alors que c'est bien ce qu'on fait.

C'est grave, psy :-)

[...]

| Et,
| avant que tu ne le proposes, je n'aime pas non plus l'idée
| d'abuser du for en écrivant « for (TypeDeX x; flux >> x;) ».

Je ne suis pas sûr que ce soit de l'abus. Des conversations avec celui
a inventé la déclaration dans les for/while/switch, j'ai la nette
impression que cette situation est certainement l'un des cas naturels
que cette introduction est censée faciliter. Mais je suppose que cela
de la définition de « abus(er) »

| Désolé pour ceux que ça déroute.

Je ne suis pas dérouté, juste amusé :-)

-- Gaby
Avatar
Michel Michaud
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.) :-)

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

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.
Pense à ceci pour mieux voir l'intérêt :

for(;;)
{
int nb;
double x;
flux >> nb >> x;
string texte;
getline(flux, texte);
/***/
if (flux.fail()) break;
/***/
Utiliser nb, x et texte...
}

Ici on a trois variables dont on ne veut pas « salir » notre
code... Par ailleurs, essaie de récrire ça, qui est pourtant de
la même logique de base que l'exemple précédent, de façon aussi
simple et lisible avec un « while faussement boucle et demie ».

Je crois que « l'idiomatique » tient pour quelques cas simples
et qui proviennent de C où on déclarait les variables au début
des blocs. En C++, on peut faire mieux et, comme dans bien
d'autres cas, il vaut mieux oublier comment on faisait en C.

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


Avatar
Andre Heinen
On Wed, 15 Jun 2005 03:59:00 -0400, "Michel Michaud"
wrote:

Ça démontre une crainte de coder une vraie boucle et
demie alors que c'est bien ce qu'on fait.


Je ne crains pas les boucles et demies, mais...

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.

--
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
Michel Michaud
Dans le message ,
"Michel Michaud" writes:

Ça démontre une crainte de coder une vraie boucle et
demie alors que c'est bien ce qu'on fait.


C'est grave, psy :-)


Sérieusement, je crois que oui.


Et, avant que tu ne le proposes, je n'aime pas non plus l'idée
d'abuser du for en écrivant « for (TypeDeX x; flux >> x;) ».


Je ne suis pas sûr que ce soit de l'abus. Des conversations avec
celui a inventé la déclaration dans les for/while/switch, j'ai la
nette impression que cette situation est certainement l'un des cas
naturels que cette introduction est censée faciliter. Mais je


Et n'a-t-il pas aussi inventé le fait que break puisse sortir
des boucles pour qu'on puisse faire des boucles et demie (et
plus...) ?

suppose que cela de la définition de « abus(er) »


Oui, c'est sûrement un cas où l'abus pour quelqu'un est un heureux
hasard pour un autre :-)

C'est de l'abus dans le sens où ce n'est pas une forme qui permet
de toujours faire ce qu'on veut, c'est presque par hasard qu'on
peut l'utiliser. S'il faut trop réfléchir pour choisir une forme,
et si l'on doit la changer quand le code change un tout petit
peu, ça me semble de l'abus. Par exemple ceci ne fonctionne pas,
simplement parce que x et y n'ont pas le même type :

for (int x, double y; flux >> x >> y;) {}

On peut régler le problème en déclarant une des deux variables
avant le for, au hasard, ce qui l'introduira dans une portée
plus grande que l'autre, mais on s'entend, j'espère, pour dire
qu'il vaut alors mieux déclarer les deux variables avant et
mettre un while... sinon pour faire de l'obfuscation. (évidemment
je ne ferais ni l'un ni l'autre, car je ferais une vraie boucle
et demie, pour ce cas « naturel »...)

Désolé pour ceux que ça déroute.


Je ne suis pas dérouté, juste amusé :-)


Ça me fait plaisir :-)

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


Avatar
kanze
Jean-Marc Bourguet wrote:
"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. On va
chercher instinctivement la nuance pour s'apercevoir qu'il n'y
en a pas.


Tout à fait. L'importance des idiomes, c'est qu'on les reconnaît
tout de suite, sans y poser de questions. Ici, j'ai quelque
lignes en plus, ce qui fait poser la question pourquoi.

Ici, aussi, j'ai un break enfouillé quelque part en plein milieu
de la boucle, où on ne le voit pas à première vue. Mais je peux
imaginer facilement des solutions à ce problème, au niveau de la
mise en page. Et à condition que le « utilisation de x... » soit
extrèmement courte, mais ça, c'est une condition générale, qui
vaut pour toutes les façons d'écrire la boucle. Aussi, il y a un
problème avec toutes les solutions auxquelles je pourrais
penser : c'est qu'il ne sont pas idiomatiques, et le lecteur va
se poser la question : pourquoi ce drôle de formattage ? (Et
pourquoi j'ai une boucle dont les invariantes changent en cours
de route ?)

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

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


Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

[...]

| >> Et, avant que tu ne le proposes, je n'aime pas non plus l'idée
| >> d'abuser du for en écrivant « for (TypeDeX x; flux >> x;) ».
| >
| > Je ne suis pas sûr que ce soit de l'abus. Des conversations avec
| > celui a inventé la déclaration dans les for/while/switch, j'ai la
| > nette impression que cette situation est certainement l'un des cas
| > naturels que cette introduction est censée faciliter. Mais je
|
| Et n'a-t-il pas aussi inventé le fait que break puisse sortir
| des boucles pour qu'on puisse faire des boucles et demie (et
| plus...) ?

Il n'a pas inventé le break, mais je doute fort que s'il l'avait fait
c'eût été pour cette construction. La sémantique naturelle de for()
dans ce cas convient sans qu'on ait besoin d'ajouter un break
explicit.

| > suppose que cela de la définition de « abus(er) »
|
| Oui, c'est sûrement un cas où l'abus pour quelqu'un est un heureux
| hasard pour un autre :-)
|
| C'est de l'abus dans le sens où ce n'est pas une forme qui permet
| de toujours faire ce qu'on veut, c'est presque par hasard qu'on
| peut l'utiliser.

définis plus précisemment ce que tu entends pas « ce n'est pas une forme
qui permet de toujours faire ce qu'on veut. »

Le C++ ne me fait pas mon thé, cela devient-il un abus lorsque je
l'utilise pour accomplir d'autres tâches ?

| S'il faut trop réfléchir pour choisir une forme,
| et si l'on doit la changer quand le code change un tout petit
| peu, ça me semble de l'abus.

Lorsque j'écris un progamme, je réflechis au choix des classes, des
fonctions et des variables. Donc si je comprends bien, c'est de l'abus
parce que je ne peux pas toujours utiliser des variables, ou toujours
utiliser des fonctions et je dois réfléchir ?

| Par exemple ceci ne fonctionne pas,
| simplement parce que x et y n'ont pas le même type :
|
| for (int x, double y; flux >> x >> y;) {}

Ceci non plus ne fonctionne pas

int main() {
j'aimerais du thé pour 10h et du café pour 13h30;
merci;
}

-- Gaby
Avatar
Jean-Marc Bourguet
"Michel Michaud" writes:

for(;;)
{
int nb;
double x;
flux >> nb >> x;
string texte;
getline(flux, texte);
/***/
if (flux.fail()) break;
/***/
Utiliser nb, x et texte...
}

Ici on a trois variables dont on ne veut pas « salir » notre
code... Par ailleurs, essaie de récrire ça, qui est pourtant de la
même logique de base que l'exemple précédent, de façon aussi simple
et lisible avec un « while faussement boucle et demie ».


Le probleme est que je ne considere pas le code ci-dessus comme
acceptable.

Tout d'abord, le format accepte manque d'homogeneite. Il ne rentre
pas dans le cadre des formats libres -- a cause du getline qui n'a un
effet que si le texte suit le double -- ni des formats par ligne -- a
cause du passage a la ligne autorise entre l'entier et le double. Je
me demande aussi si le fait qu'on lit les blancs apres le double est
voulu.

Ensuite, le traitement des erreurs de format est totalement absent et
le code montre rend impossible d'avoir des messages d'erreur
acceptables.

J'ai deux techniques pour lire des fichiers:

- ou le format est par ligne et donc la forme idiomatique tient la
route
while (getline(flux, line)) {
}

- ou j'ai un couple analyseur lexical/analyseur grammatical (ecrit a
la main ou avec des generateurs) et donc on n'est plus dans le cas
des IOStream meme si la version la plus simple pour l'analyseur
lexical est une classe du genre
enum TokenKind { NoTk, IdentTk, StringTk, NumberTk, PtherTk, EOFTk };
struct Token {
TokenKind kind;
std::string lexem;
};
std::istream& operator>>(std::istream&, Token&);

Dans tous les cas le programme reagit a ce qui a ete entre et ne lit
pas en aveugle en supposant que le format est correct.

A+

--
Jean-Marc FAQ de fclc++:
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF:
http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de
usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Jean-Marc Bourguet
"Michel Michaud" writes:

for(;;)
{
int nb;
double x;
flux >> nb >> x;
string texte;
getline(flux, texte);
/***/
if (flux.fail()) break;
/***/
Utiliser nb, x et texte...
}

Ici on a trois variables dont on ne veut pas « salir » notre
code... Par ailleurs, essaie de récrire ça, qui est pourtant de la
même logique de base que l'exemple précédent, de façon aussi simple
et lisible avec un « while faussement boucle et demie ».


Le probleme est que je ne considere pas le code ci-dessus comme
acceptable.

Tout d'abord, le format accepte manque d'homogeneite. Il ne rentre
pas dans le cadre des formats libres -- a cause du getline qui n'a un
effet que si le texte suit le double -- ni des formats par ligne -- a
cause du passage a la ligne autorise entre l'entier et le double. Je
me demande aussi si le fait qu'on lit les blancs apres le double est
voulu.

Ensuite, le traitement des erreurs de format est totalement absent et
le code montre rend impossible d'avoir des messages d'erreur
acceptables.

J'ai deux techniques pour lire des fichiers:

- ou le format est par ligne et donc la forme idiomatique tient la
route
while (getline(flux, line)) {
}

- ou j'ai un couple analyseur lexical/analyseur grammatical (ecrit a
la main ou avec des generateurs) et donc on n'est plus dans le cas
des IOStream meme si la version la plus simple pour l'analyseur
lexical est une classe du genre
enum TokenKind { NoTk, IdentTk, StringTk, NumberTk, OtherTk, EOFTk };
struct Token {
TokenKind kind;
std::string lexem;
};
std::istream& operator>>(std::istream&, Token&);

Dans tous les cas le programme reagit a ce qui a ete entre et ne lit
pas en aveugle en supposant que le format est correct.

A+

--
Jean-Marc FAQ de fclc++:
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF:
http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de
usenet-fr: http://www.usenet-fr.news.eu.org

1 2 3