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
florian wrote:
On 3 mai, 18:33, Laurent Deniau wrote:
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 wrote:
On 3 mai, 18:33, Laurent Deniau <laurent.den...@cern.ch> wrote:
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 ;-).
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
On 3 mai, 19:18, Harpo wrote:
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.
On 3 mai, 19:18, Harpo <inva...@invalid.invalid> wrote:
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.
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 -- <http://www.levenez.com/> Unix is not only an OS, it's a way of life.
Stephane Chazelas
2007-05-3, 16:08(+00), Marc Boyer:
Le 03-05-2007, florian a écrit :
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 <stdio.h> 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
2007-05-3, 16:08(+00), Marc Boyer:
Le 03-05-2007, florian <lechewal@gmail.com> a écrit :
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 <stdio.h>
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.
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 <stdio.h> 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
En news:, florian va escriure:
On 3 mai, 18:33, Laurent Deniau wrote:
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
En news:1178211064.382579.280750@n59g2000hsh.googlegroups.com,
florian va escriure:
On 3 mai, 18:33, Laurent Deniau <laurent.den...@cern.ch> wrote:
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.)
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
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
En news:87r6pxpsg3.fsf@news.bourguet.org, 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.
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.