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

zlib marche pô :-(

8 réponses
Avatar
TSalm
Bonjour,

J'essaye d'utiliser zlib.
En faisant un programme qui est censé afficher le contenu d'un fichier
compressé, je me rencontre un problème : les données sont différent selon
la taille de mon buffer.
En bon débutant, j'imagine que la zlib est parfaitement stable et que
c'est moi le bug ;-)

J'ai donc fait un programme de test pour illustrer mon problème.
L'idée est d'afficher la taille totale lue du fichier compressé pour
chaque taille de buffer.

Je n'arrive vraiment pas à trouver où mon code cloche, je le soumet donc
aux esprits éclairés de ce ng.

/* ---------------- CODE --------------- */

#include <iostream>
#include <exception>

#include <zlib.h>
#include <libgen.h>


using namespace std;


string exeName;

void displayContent(char* zFilePath,unsigned buffSz)
{
//unsigned buffSz = 200;

unsigned szRead;
char buffer[ buffSz ];
gzFile gzf = gzopen(zFilePath,"rb");

if ( gzf == NULL )
throw exception() ;

unsigned szTotal = 0;

while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )
{
cout << szRead << " ";
szTotal += szRead;

// for (int i=0;i<szRead;++i)
// putchar( buffer[i] ) ;
}
cout << endl;

gzclose( gzf );

if ( szRead == -1 )
throw exception();

cout << "For size " << buffSz << " - size total:" << szTotal << endl;
}

void displayUsage()
{
cout<< "Display the content of a gzipped file\n"
<< " Usage: " << exeName << " [file]\n"
<< endl;
}

int main(int argc,char** argv)
{
// Initialize
exeName = basename(argv[0]);

// If there's errors in arg, display usage
if ( argc != 2 )
{
displayUsage();
} else {
for (unsigned i=1;i<1024;i*=2)
displayContent( argv[1] ,i );
}


}
/* ------------------------------------- */

8 réponses

Avatar
Fabien LE LEZ
On Sat, 05 Dec 2009 01:06:54 +0100, TSalm :

void displayContent(char* zFilePath,unsigned buffSz)



Attention, tu indiques ici que la fonction va modifier "zFilePath".

unsigned szRead;



Beurk. La notation hongroise est (normalement) abandonnée depuis
longtemps, surtout en C++.
En fait, il s'agissait au départ d'une bonne idée, mais comprise
totalement de travers.
Plus d'infos ici : http://www.joelonsoftware.com/articles/Wrong.html

char buffer[ buffSz ];



Illégal en C++, puisque buffSz n'est pas une constante connue à la
compilation. À moins que ça ait été rajouté dans la nouvelle norme ?

(En revanche, c'est légal en C. Du coup, je me demande si tu ne t'es
pas trompé de forum.)
Avatar
Fabien LE LEZ
On Sat, 05 Dec 2009 01:06:54 +0100, TSalm :

while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )



L'erreur dans ton code est probablement ici : tu t'es emmêlé les
pinceaux dans les parenthèses. Du coup, szRead vaut soit 1 (en fait,
"true" converti en un entier), soit 0 (false converti en un entier).
Avatar
TSalm
>
while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )



L'erreur dans ton code est probablement ici : tu t'es emmêlé les
pinceaux dans les parenthèses. Du coup, szRead vaut soit 1 (en fait,
"true" converti en un entier), soit 0 (false converti en un entier).




C'est exact.
J'ai remplacé :

while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )
{

par :

while (true)
{
szRead = gzread( gzf, buffer, buffSz );
if ( szRead <= 0 )
break;

et ça fonctionne.
<<szRead>> n'est plus à chaque fois égal 1.

Par contre, je ne comprends pas pourquoi mon code ne marchait pas.
Pourquoi mon <<szRead>> était alimenté par 1 !?
Avatar
TSalm
Le Sat, 05 Dec 2009 21:35:46 +0100, TSalm a écrit:


while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )



L'erreur dans ton code est probablement ici : tu t'es emmêlé les
pinceaux dans les parenthèses. Du coup, szRead vaut soit 1 (en fait,
"true" converti en un entier), soit 0 (false converti en un entier).




C'est exact.
J'ai remplacé :

while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )
{

par :

while (true)
{
szRead = gzread( gzf, buffer, buffSz );
if ( szRead <= 0 )
break;

et ça fonctionne.
<<szRead>> n'est plus à chaque fois égal 1.

Par contre, je ne comprends pas pourquoi mon code ne marchait pas.
Pourquoi mon <<szRead>> était alimenté par 1 !?




Bon. Le fichier décompressé ne correspond pas.
Etant une librairie C, je vais poser la question du côté du ng
fr.comp.lang.c
Avatar
TSalm
Le Sat, 05 Dec 2009 02:43:18 +0100, Fabien LE LEZ
a écrit:

On Sat, 05 Dec 2009 01:06:54 +0100, TSalm :

void displayContent(char* zFilePath,unsigned buffSz)



Attention, tu indiques ici que la fonction va modifier "zFilePath".

unsigned szRead;



Beurk. La notation hongroise est (normalement) abandonnée depuis
longtemps, surtout en C++.
En fait, il s'agissait au départ d'une bonne idée, mais comprise
totalement de travers.
Plus d'infos ici : http://www.joelonsoftware.com/articles/Wrong.html

char buffer[ buffSz ];



Illégal en C++, puisque buffSz n'est pas une constante connue à la
compilation. À moins que ça ait été rajouté dans la nouvelle norme ?

(En revanche, c'est légal en C. Du coup, je me demande si tu ne t'es
pas trompé de forum.)




Mais le C++ ne doit pas être 100% compatible avec le C ?
Avatar
Fabien LE LEZ
On Sat, 05 Dec 2009 23:13:53 +0100, TSalm :

Mais le C++ ne doit pas être 100% compatible avec le C ?



Non, pas spécialement. Il y a une certaine compatibilité pour des
raisons historiques, c'est tout.
Avatar
TSalm
> C'est exact.
J'ai remplacé :

while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )
{

par :

while (true)
{
szRead = gzread( gzf, buffer, buffSz );
if ( szRead <= 0 )
break;




Oups.
Faute d'inattention sur les parenthèses. Ca ferait mieux l'affaire :
while ( ( szRead = gzread( gzf, buffer, buffSz ) ) > 0 )
Avatar
TSalm
Le Sun, 06 Dec 2009 16:24:19 +0100, TSalm a écrit:

C'est exact.
J'ai remplacé :

while ( ( szRead = gzread( gzf, buffer, buffSz ) > 0 ) )
{

par :

while (true)
{
szRead = gzread( gzf, buffer, buffSz );
if ( szRead <= 0 )
break;




Oups.
Faute d'inattention sur les parenthèses. Ca ferait mieux l'affaire :
while ( ( szRead = gzread( gzf, buffer, buffSz ) ) > 0 )



J'ai trouvé d'où vient mon problème : la <<zlib>> ne gére pas le format
zip :-(
Et si la zlib ne reconnait pas un format, il le lit sans décompression.
La taille que me retourne mon programme est la taille du fichier compressé.