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

stdin

13 réponses
Avatar
Jean Pierre Daviau
Bonjour à tous et bonne année,

Peut-on définir stdin comme fichier.txt dans une fonction?

ex: stdin = fopen('fichier.txt' , 'r');
ex: stdin = fopen(argv[1], 'r');
--
Grand merci

Jean Pierre Daviau
--
windows Xp
asus p4 s533/333/133
Intel(R) Celeron (R) CPU 2.00 GHz
Processor Radeon7000 0x5159 agp

10 réponses

1 2
Avatar
Mickaël Wolff
Bonjour à tous et bonne année,

Peut-on définir stdin comme fichier.txt dans une fonction?

ex: stdin = fopen('fichier.txt' , 'r');
ex: stdin = fopen(argv[1], 'r');


/* chstdin.c
* gcc -o chstdin chstdin.c -Wall -ansi -pedantic
*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
int c ;

fclose(stdin) ;
stdin = fopen("chstdin.c", "r") ;

while((c = fgetc(stdin)) != EOF)
putchar(c) ;

return 0 ;
}

Ça marche. Par contre, je ne sais pas si la zone mémoire pointée par
stdin est libérée par fclose.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Avatar
Vincent Lefevre
Dans l'article <4798d10a$0$3194$,
Mickaël Wolff écrit:
[...]
int main(int argc, char ** argv)
{
int c ;

fclose(stdin) ;
stdin = fopen("chstdin.c", "r") ;

while((c = fgetc(stdin)) != EOF)
putchar(c) ;

return 0 ;
}

Ça marche. Par contre, je ne sais pas si la zone mémoire pointée par
stdin est libérée par fclose.


A priori, cela ne concerne pas grand chose.

Mais un autre point est que la norme C ne garantit pas que ce sera
l'entrée standard pour la commande lancée par un system(). Dans la
pratique, sur certains systèmes Unix, le problème se pose pour stdout
et stderr.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Jean Pierre Daviau
Nope.

Cela a avoir avec freopen peut-être . . .


"Mickaël Wolff" a écrit dans le
message de news: 4798d10a$0$3194$
Bonjour à tous et bonne année,

Peut-on définir stdin comme fichier.txt dans une fonction?

ex: stdin = fopen('fichier.txt' , 'r');
ex: stdin = fopen(argv[1], 'r');


/* chstdin.c
* gcc -o chstdin chstdin.c -Wall -ansi -pedantic
*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
int c ;

fclose(stdin) ;
stdin = fopen("chstdin.c", "r") ;

while((c = fgetc(stdin)) != EOF)
putchar(c) ;

return 0 ;
}

Ça marche. Par contre, je ne sais pas si la zone mémoire
pointée par
stdin est libérée par fclose.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org



Avatar
Jean Pierre Daviau
Ha! ha . . .

/* chstdin.c
* gcc -o chstdin chstdin.c -Wall -ansi -pedantic
* Usage : chstdin < chstdin.c
*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv){
int c ;
freopen("chstdin.c", "r", stdin);

while((c = fgetc(stdin)) != EOF)
putchar(c) ;

return 0 ;
}
Avatar
Charlie Gordon
"Mickaël Wolff" a écrit dans le message de news:
4798d10a$0$3194$
Bonjour à tous et bonne année,

Peut-on définir stdin comme fichier.txt dans une fonction?

ex: stdin = fopen('fichier.txt' , 'r');
ex: stdin = fopen(argv[1], 'r');


/* chstdin.c
* gcc -o chstdin chstdin.c -Wall -ansi -pedantic
*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
int c ;

fclose(stdin) ;
stdin = fopen("chstdin.c", "r") ;

while((c = fgetc(stdin)) != EOF)
putchar(c) ;

return 0 ;
}

Ça marche. Par contre, je ne sais pas si la zone mémoire pointée par
stdin est libérée par fclose.


Ca marche par miracle dans ton environnement, mais ce n'est pas portable et
totalement déconseillé.
Pour faire "pointer" stdin sur un fichier, il faut utiliser freopen:

freopen("chstdin.c", "r", stdin);

--
Chqrlie.


Avatar
Vincent Lefevre
Dans l'article <479c9088$0$955$,
Charlie Gordon écrit:

Ca marche par miracle dans ton environnement, mais ce n'est pas portable et
totalement déconseillé.
Pour faire "pointer" stdin sur un fichier, il faut utiliser freopen:

freopen("chstdin.c", "r", stdin);


Ça a un peu plus de chance de marcher que le fclose + fopen, mais là
encore, rien n'est garanti (surtout s'il s'agit de stdout ou stderr).
Cf la discussion sur:

http://sourceware.org/bugzilla/show_bug.cgi?idh2

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Antoine Leca
En news:20080128011905$, Vincent Lefevre va
escriure:
Dans l'article <479c9088$0$955$,
Charlie Gordon écrit:

Ca marche par miracle dans ton environnement, mais ce n'est pas
portable et totalement déconseillé.
Pour faire "pointer" stdin sur un fichier, il faut utiliser freopen:

freopen("chstdin.c", "r", stdin);


Ça a un peu plus de chance de marcher que le fclose + fopen, mais là
encore, rien n'est garanti


Qu'est-ce qui n'est pas garanti ?


(surtout s'il s'agit de stdout ou stderr).
Cf la discussion sur:
http://sourceware.org/bugzilla/show_bug.cgi?idh2


Le « bogue » survient lorsque:

- on utilise un environnement « genre Posix », avec des descripteurs de
fichiers numérotés 0, 1 et 2 pour respectivement l'entrée standard, la
sortie standard, la sortie erreur ;

- on ferme stdin avec fclose(stdin), donc on ferme le descripteur 0 ;

- on réassigne stdout avec freopen( , stdout), ce qui a pour effet
d'associer stdout au descripteur 0 (norme POSIX) ;

- on utilise des fonctions (de bibliothèques ou utilisateur) qui /supposent/
que stdout correspond au descripteur n° 1 (ce qui n'est plus vrai), BOUM.


Je ne dis pas que cela n'arrive jamais, mais je crois que le cas est un peu
limite...
Par ailleurs, il me semble que si l'on s'abstient de fermer stdin (ou si on
le fait après), on n'observe plus de dysfonctionnement : cela me semble un
contournement raisonnable.

En tous cas, il me semble exagéré d'en conclure qu'il ne faut pas utiliser
freopen() pour rediriger stdin, comme tu sembles le faire ci-dessus.


Antoine


Avatar
Aris
En news:20080128011905$, Vincent Lefevre va
escriure:
Dans l'article <479c9088$0$955$,
Charlie Gordon écrit:

Ca marche par miracle dans ton environnement, mais ce n'est pas
portable et totalement déconseillé.
Pour faire "pointer" stdin sur un fichier, il faut utiliser freopen:
freopen("chstdin.c", "r", stdin);
Ça a un peu plus de chance de marcher que le fclose + fopen, mais là

encore, rien n'est garanti


Qu'est-ce qui n'est pas garanti ?


(surtout s'il s'agit de stdout ou stderr).
Cf la discussion sur:
http://sourceware.org/bugzilla/show_bug.cgi?idh2


Le « bogue » survient lorsque:

- on utilise un environnement « genre Posix », avec des descripteurs de
fichiers numérotés 0, 1 et 2 pour respectivement l'entrée standard, la
sortie standard, la sortie erreur ;

- on ferme stdin avec fclose(stdin), donc on ferme le descripteur 0 ;

- on réassigne stdout avec freopen( , stdout), ce qui a pour effet
d'associer stdout au descripteur 0 (norme POSIX) ;

- on utilise des fonctions (de bibliothèques ou utilisateur) qui /supposent/
que stdout correspond au descripteur n° 1 (ce qui n'est plus vrai), BOUM.


Je ne dis pas que cela n'arrive jamais, mais je crois que le cas est un peu
limite...
Par ailleurs, il me semble que si l'on s'abstient de fermer stdin (ou si on
le fait après), on n'observe plus de dysfonctionnement : cela me semble un
contournement raisonnable.

En tous cas, il me semble exagéré d'en conclure qu'il ne faut pas utiliser
freopen() pour rediriger stdin, comme tu sembles le faire ci-dessus.


Antoine

LA solution c'est de ne pas prendre comme hypothèse qu'on va lire depuis

stdin, et de rajouter un parametre de type FILE* à chaque fonction du
code pour définir l'entrée. C'est d'ailleur ce qui aurait du être fait
en premier dans un bon design de code.
Avec ça, plus de malentendu possible, on ouvre un fichier ou on utilise
stdin. Plus besoin de fermer stdin ou stdout (d'ailleur pourquoi
faudrait-il les fermer ?)



Avatar
Erwan David
Aris écrivait :

LA solution c'est de ne pas prendre comme hypothèse qu'on va lire
depuis stdin, et de rajouter un parametre de type FILE* à chaque
fonction du code pour définir l'entrée. C'est d'ailleur ce qui aurait
du être fait en premier dans un bon design de code.
Avec ça, plus de malentendu possible, on ouvre un fichier ou on
utilise stdin. Plus besoin de fermer stdin ou stdout (d'ailleur
pourquoi faudrait-il les fermer ?)


Sur un système POSIX, un démon doit les fermer pour libérer son
terminal.

Donc, pourquoi ne faudrait-il pas les fermer ?

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé

Avatar
Antoine Leca
Dans news:479dd7e3$0$31998$,
au milieu d'une discussion sur freopen(), Aris écrivit:
LA solution c'est de ne pas prendre comme hypothèse qu'on va lire
depuis stdin, et de rajouter un parametre de type FILE* à chaque
fonction du code pour définir l'entrée.


Désolé, mais je ne vois pas le rapport (surtout avec ce que j'ai écrit).


C'est d'ailleur ce qui aurait du être fait
en premier dans un bon design de code.


Si tu utilises des bibliothèques ou plus généralement du code déjà écrit, ou
si tu écris un programme destiné à être mis en ouvre comme filtre (raisons
les plus évidentes pour utiliser freopen()), cet argument est irrecevable.

Il ne l'est pas plus si tu travailles dans un environnement constraint en
terme de nombre de pointeurs utilisables.


Quant à argumenter comme quoi les filtres (tubes, pipes) inventés par
McIlroy pour Unix sont à rejeter comme étant un exemple de mauvaise
architecture, on peut poursuivre l'argument et dire que le langage C devrait
d'abord être banni et que dans un bon dessin de code l'on devrait d'abord
utiliser [insérer ici celui qui mettra à votre avis le plus de flammes dans
la discussion].

Cette discussion n'ayant aucun intérêt dans ce groupe, je ne la poursuivrais
pas.


Antoine

1 2