Deux passes de stdin

Le
florian
Bonjour,

je vais surement me faire traiter de noob ;), mais je bloque un peu..

J'aimerai lire deux fois stdin, à l'aide de fgets.

La première passe se déroule bien.

Pour revenir au début, j'ai tenté un rewind(stdin).

Mais, lors de la seconde passe, feof est vrai, et fgets renvoie
NULL

Surement un truc tout bête mais..

a+
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Marc Boyer
Le #1005334
Le 03-05-2007, florian
je vais surement me faire traiter de noob ;), mais je bloque un peu..

J'aimerai lire deux fois stdin, à l'aide de fgets.


Tu ne peux pas.

La première passe se déroule bien.

Pour revenir au début, j'ai tenté un rewind(stdin).


Et tu as regardé son code de retour ? Il devrait te retourner
EBADF The stream specified is not a seekable stream.

Surement un truc tout bête mais..


Non, non, c'est simplement impossible.

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

Laurent Deniau
Le #1005333
florian wrote:
Bonjour,

je vais surement me faire traiter de noob ;), mais je bloque un peu..

J'aimerai lire deux fois stdin, à l'aide de fgets.

La première passe se déroule bien.

Pour revenir au début, j'ai tenté un rewind(stdin).

Mais, lors de la seconde passe, feof est vrai, et fgets renvoie
NULL...

Surement un truc tout bête mais..


C'est impossible, il faut bufferiser ce que tu lis durant la 1ere passe
qque part.

a+, ld.

florian
Le #1005332
On 3 mai, 18:33, Laurent Deniau

C'est impossible, il faut bufferiser ce que tu lis durant la 1ere passe
qque part.

a+, ld.


mh, c'est du 150Mo compressé (lu avec zcat fic | prog)..
Dommage..

Je vais chercher une autre solution
merci & a+

Laurent Deniau
Le #1005331
florian wrote:
On 3 mai, 18:33, Laurent Deniau
C'est impossible, il faut bufferiser ce que tu lis durant la 1ere passe
qque part.

a+, ld.


mh, c'est du 150Mo compressé (lu avec zcat fic | prog)..
Dommage..


Donc tu n'as pas besoin de lire 150Mo mais seulement la taille des blocs
compresses, en general <1Mo qui decompresses devrait faire <10Mo. Ce
qu'il faut que tu detectes/calcules, c'est quel est le plus gros rewind
que tu aurais a faire. Si tu ne le sais pas a l'avance, tu alloues les
150Mo sachant que le systeme te les fourniras au fur et a mesure que tu
y accedes (en tout cas sous Linux).

Perso mes parsers utilisent la technique du read+commit ou read+rollback
comme les DBs. C'est beaucoup plus simple: si le parsing reussi ->
commit, s'il echoue -> rollback et on essaie autre chose (sous forme de
combinateurs). C'est moins optimal que tu lex/yacc mais tellement plus
reposant, on ecrit directement en C qqchose qui ressemble a du BNF ;-).

a+, ld.


florian
Le #1005328
On 3 mai, 19:18, Harpo
Je vois 2 solutions :

1 - séparer ton programme en 2 :
zcat fic | prog1
zcat fic | prog2

2 - passer par un fichier temporaire :
zcat fic > tmp
et ouvrir tmp au lieu d'utiliser stdin.


Le problème avec la première solution est que le prog2 à besoin des de
ce qui est fait sur le prog1.

Pour la seconde solution, le but du pipe sur le zcat est de justement
ne pas avoir à décompresser.

Jean-Marc Bourguet
Le #1002769
florian
On 3 mai, 18:33, Laurent Deniau

C'est impossible, il faut bufferiser ce que tu lis durant la 1ere passe
qque part.

a+, ld.


mh, c'est du 150Mo compressé (lu avec zcat fic | prog)..
Dommage..

Je vais chercher une autre solution


popen et ouvrir le fichier deux fois

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Eric Levenez
Le #1002768
Le 3/05/07 18:51, dans

mh, c'est du 150Mo compressé (lu avec zcat fic | prog)..
Dommage..


Si tu utilisais la zlib, tu n'aurais pas besoin de zcat et ton programme
ferais directement des gz[d]open, gzread ou gzgets...

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.

Stephane Chazelas
Le #1002766
2007-05-3, 16:08(+00), Marc Boyer:
Le 03-05-2007, florian
je vais surement me faire traiter de noob ;), mais je bloque un peu..

J'aimerai lire deux fois stdin, à l'aide de fgets.


Tu ne peux pas.

La première passe se déroule bien.

Pour revenir au début, j'ai tenté un rewind(stdin).


Et tu as regardé son code de retour ? Il devrait te retourner
EBADF The stream specified is not a seekable stream.


rewind n'a pas de code de retour. Utiliser fseek si on veut un code
de retour.


Surement un truc tout bête mais..


Non, non, c'est simplement impossible.


Non, seulement si stdin pointe sur un fichier qui ne permet pas de
lseek (comme un pipe ou un tty). Ca n'a rien a voir avec le fait
que ce soit stdin ou un autre FILE* (au moins chez les Unix).

~$ cat > a.c
#include int main() {
char buf[2048];
gets(buf);
puts(buf);
rewind(stdin);
gets(buf);
puts(buf);
return 0;
}
~$ make a
cc -c -o a.o a.c
cc a.o -o a
a.o: In function `main':
a.c:(.text+0x1e): warning: the `gets' function is dangerous and should not be used.
~$ seq 2 | ./a
1
2
~$ seq 2 > b
~$ ./a < b
1
1

Evidemment, on ne peut pas revenir en arriere sur un pipe ou un
tty, question de bon sens.

--
Stéphane


Antoine Leca
Le #1002765
En news:,
florian va escriure:
On 3 mai, 18:33, Laurent Deniau

C'est impossible, il faut bufferiser ce que tu lis durant la 1ere
passe qque part.


mh, c'est du 150Mo compressé (lu avec zcat fic | prog)..


Il n'y a pas de solution magique, ou bien tu mets toi-même en tampon ou en
fichier ou que-sais-je tes 150×n Mo décomprimés, ou bien tu exécutes deux
fois l'algorithme de décompression sur les 150 Mo comprimés.

Dans tous les cas, il faut le faire faire _explicitement_, les ordinateurs
(en C) ne sont pas encore suffisament intelligents pour savoir que tu veux
faire et stocker dans le doute le résultat de la décompression dans un «
petit » coin de la mémoire...

(Surtout que 150×n Mo décomprimés, cela doit représenter un bon bout de la
dite mémoire.)


Antoine


Antoine Leca
Le #1002764
En news:, Jean-Marc Bourguet va escriure:

popen et ouvrir le fichier deux fois


Si la première passe a besoin de lire le fichier complètement avant que ne
se lance la seconde passe, tu vas demander au système de stocker en mémoire
tampon la totalité des 150×n Mo décomprimés (en attente de lecture sur le
deuxième descripteur de fichier).

Et un certain nombre d'implémentation vont te faire un bras d'honneur très
vite (par exemple, Unix original ne permet de stocker les tubes que dans les
entrées directes des inodes, cela risque de ne pas suffir ici;-)); tandis
que d'autres vont essayer de faire de leur mieux, et risquent de swapper
férocement.

Sans parler des systèmes plus exotiques (Windows ? que dit Posix ?) qui vont
refuser tout court la seconde ouverture.


Antoine

Publicité
Poster une réponse
Anonyme