IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Remplir un fichier binaire de BITS !!!!


Sujet :

C

  1. #41
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    bon alors la j'ai un souci...

    si je compresse un texte ou j'ecris des phrases comme ca ca marche (a la decompression je retrouve mon texteOK)

    si je rajoute a la fin un '#', j'obtiens un texte ou c'est nimporte quoi ... seules quelques lettres sont ok mais faut vraiment bien chercher ....

    ta une idee pour ce bug ????

  2. #42
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    je viens de voir un truc ...

    par exemple : j'ai mon texte qui ne contient pas de parenthese ouvrante '('

    je le compresse puis decompresse : tout est OK

    si je rajoute une parenthese ouvrante a la fin de ce texte, BUG

    si j'en rajoute une en plus ailleurs dans le texte ---> OK

    tu vois le truc ????...

    je continue mes tests

  3. #43
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    beh c vraiment bizarre

    si je compresse le texte

    beh ca marche


    et ca depend pas non plus de la longueur car j'ai fait un texte avec une copie un nombe incaculable de fois aabbc( et ca marche...

  4. #44
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    hmmm, je ne veux pas faire genre le raleur de service, mais tu te fais un topic où tu parles tout seul, là ?
    Plutot que de poser tes questions quand elles arrivent, tu ne peux pas essayer de centraliser tout ca ? (ce sera quand même plus simple si tu veux qu'on t'aide....)

    enfin bon, c'est ce j'en dis, moi....
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  5. #45
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    ouais ta raison je me suis rendu compte de ca .....

    mais j'ai un defaut c'est que des que je pense a un truc je balance un post ...

    enfin pour resumer j'ai plus qu'un prob maintenant c'est celui que j'ai expliqué plus haut et qui fait que la compression de certains textes marche, mais ne marche pas pour d'autres, plus "complexes"

    il faudrait que je trouve un exemple qui foire avec peu de caracteres differents de facon a pouvoir faire une trace mais je sais pas si je vais y arriver pke ca semble toujours marcher quand ya peu de caracteres differents......

  6. #46
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par ben13
    En stockant le tab des frequences tu peut reconstruire l'arbre en utilisant la meme fonction qu'au debut et donc ta les codes, et tu peux donc reconstruire, encore avec la meme fonction, le tableau de codes ... c genial !!!! (bref tavais raison quoi...)
    Tu vois que tu as compris pourquoi c'est plus simple de stocker les fréquences...

    Citation Envoyé par ben13
    par contre si je fais aucune optimisation et que je considere que les indices correspondent aux caracteres, le tableau mesure quand meme 256 int donc 1024 Ko .... c'est lourd
    Tu as mal compté : les caractères n'ont jamais à être stockés,ça c'est OK étant donné que tu les range séquentiellement. Mais ce n'est pas 1024 ko, mais 1024 octets... Un kilo-octet, donc. Et oui, c'est lourd, voilà pourquoi j'avais introduit ces optimisations de stockage.

    Citation Envoyé par ben13
    du coup j'ai mieux regardé les optimisations que ta fait toi
    En fait, je pense que tu t'inquiètes pour pas grand-chose : ça parait beaucoup plus complexe que ça ne l'est en réalité.

    La première chose à faire, c'est pouvoir lire et écrire le fichier bit à bit. Pour ça, tu as deux manières :
    - Soit tu encapsules complètement le truc, et tu lis N bits depuis le fichier (max : 32 bits d'un coup), renvoyés dans un unsigned long int que tu peux ensuite transformer en ce que tu veux.
    - Soit tu lis des unsigned char, et tu les "explose" en 8 booléens à la main.

    Perso, je préfère (et de loin !!) la première méthode, elle est beaucoup plus simple à utiliser et à implémenter.

    Dans le principe, ça donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    unsigned char GetNextBit ( FILE* F ) {
     
      static unsigned char Buffer ;   // Buffer de lecture.
      static unsigned char Step = 0 ; // Etape courante (0..7). Equivaut au "remplissage" du buffer.
      unsigned char Result ;
     
      if (!Step)
        // Buffer vide, on le remplit.
        fread(F,&Buffer,1,1);
     
      // Extraction du bit
      Result=((Buffer & 0x80)?1:0) ;
      // Décalage du buffer pour le prochain bit.
      Buffer=Buffer<<1;
      // Calcul de l'étape, modulo 8.
      Step=(Step+1) & 0x07 ;
      // Retour du résultat, qui vaut 1 ou 0.
      return Result ;
    }
     
    void SetNextBit ( FILE*F, unsigned char Bit ) {
     
      static unsigned char Buffer = 0 ;  // Buffer d'écriture, doit être initialisé à zéro.
      static unsigned char Step = 7 ;    // Etape courante (0..7), mais on part du poids fort.
     
      // Positionnement du bit, si nécessaire.
      if (Bit)
        Buffer = Buffer | (1<<Step) ;
      // Calcul de l'étape, modulo 8.
      // On fait "à l'envers" de la lecture, c'est normal.
      Step=(Step-1) & 0x07 ;
     
      // Vidage du buffer lorsqu'il est plein.
      if (Step==7)
        // Buffer vide, on le remplit.
        fwrite(F,&Buffer,1,1);
    }
     
    // Lecture de Count bits depuis le fichier.
    // En sortie, les Count bits de poids faible seront ceux lus depuis le fichier.
    // Le bit de poids faible est le dernier lu.
    unsigned long int ReadBits ( FILE* F, unsigned char Count ) {
     
      unsigned long int Result = 0 ;
     
      for (int i=0;i<Count;i++)
        Result = (Result << 1) | GetNextBit(F) ;
     
      return Result ;
    }
    Note : Je n'ai pas de compilateur C sous la main, ni de doc sur la CLib => il y a certainement des erreurs, et je n'ai pas testé les codes de retour, il faudra le faire. Il manque aussi WriteBits, et il faut aussi "inverser" l'ordre par rapport à ReadBits.

    Pour ton bug, ça ressemble fortement à une non-séparation des codes et/ou à une mauvaise construction de l'arbre. Utilise un debugger pour tracer ça, vérifie la séparabilité des codes en les affichant tous si nécessaire : tu les écris tous en ligne, un par ligne et en binaire, et tu trie le fichier obtenu pour vérifier ça (assez) facilement.

    (Note : j'ai fait ce post en deux temps, j'avais des trucs à faire urgents, et Pouic a raison : tu postes beaucoup trop "pour rien", pense à éditer tes messages voire à les supprimer s'il n'ont plus lieu d'être, ça simplifiera la vie de tout le monde... Le temps que je réponde, j'ai pris 4 posts en plus...).
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #47
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    Tu as mal compté : les caractères n'ont jamais à être stockés,ça c'est OK étant donné que tu les range séquentiellement. Mais ce n'est pas 1024 ko, mais 1024 octets... Un kilo-octet, donc. Et oui, c'est lourd, voilà pourquoi j'avais introduit ces optimisations de stockage.
    affectivement j'ai ecrit Ko mais je voulais ecrire o....

    La première chose à faire, c'est pouvoir lire et écrire le fichier bit à bit. Pour ça, tu as deux manières :
    - Soit tu encapsules complètement le truc, et tu lis N bits depuis le fichier (max : 32 bits d'un coup), renvoyés dans un unsigned long int que tu peux ensuite transformer en ce que tu veux.
    - Soit tu lis des unsigned char, et tu les "explose" en 8 booléens à la main.
    moi j'ai choisi la 2e methode et ca tourne alors je vais pas tout refaire ...
    ca donne ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    FILE* bin_int ( FILE* file_code, FILE* file_code_int ){
     
    	int i, j=0, testint, sortir=0, a;
    	unsigned char result;
    	unsigned char tmp[M],octet[M];
     
     
     
    	/*Lecture de huit 0 ou 1 dans le fichier pointé par file_code, et mise de ces 0 et 1 dans le tableau de M unsigned char : octet*/
    	while(1){
    		for(i=0;i<M;i++){
    			if ( fread(&testint, 1, 1, file_code ) == 1 )
    				octet[i]=testint;
    			else {
    				octet[i] = 2 ; /*On met 2 pour dire que la case ne doit pas etre comptée*/
    				sortir = 1;
    			}
    		}
     
     
    		/*Inversion du tableau octet (vers le tableau tmp) pour permettre le calcul des puissances de 2*/
    		j = 0;
    		for(i=M-1;i>=0;i--){
    			tmp[j]=octet[i];
    			j++;
    		}
     
    		/*Conversion du nombre binaire en int*/
    		a = 0;
    		while ( tmp[a] == 2 ) /*On zappe les cases remplies de 2 (cases vides)*/
    			a++;
     
    		result = 0;
    		for(i=a;i<M;i++)
    			result = result + ( tmp[i] * puissance(2,i-a) );
     
     
    		/*Ecriture du nombre en int (type unsigned char) dans le fichier pointé par file_code_int*/
    		fwrite ( &result, 1, 1, file_code_int);	
     
    		if ( sortir == 1 )
    			break;
     
    	}
     
    	fclose(file_code_int);
     
    	return file_code_int;
     
    }

    Pour ton bug, ça ressemble fortement à une non-séparation des codes et/ou à une mauvaise construction de l'arbre. Utilise un debugger pour tracer ça, vérifie la séparabilité des codes en les affichant tous si nécessaire : tu les écris tous en ligne, un par ligne et en binaire, et tu trie le fichier obtenu pour vérifier ça (assez) facilement.
    comme j'ai dit dans mon post précédent je vais essayer demain de faire une trace, ou du moins de comparer mon arbre avant compression, et mon arbre recréé pour la décompression ......

  8. #48
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    C OK !!!!

    mais je comprends quand meme rien a ce bug.

    apres vérification, mon tab_freq original avait pour fréquence du caractere NULL (code ASCII 0) 0, aprés copie dans fichier et ouverture du fichier, mon tab_freq avait pour frequence du caractere NULL 1 !!!!! HALLUCINANT comme si le tableau c'etait mal copié (juste pour cette frequence dans le fichier ) ....

    du coup obligé de ruser en remettant cette frequence a 0 apres ouverture ....

    c chiant quand meme


    enfin ca a l'air de tourner now je vais faire encore quelques tests et si c OK je vais enfin m'amuser a faire l'implémentation unix de mon script .....

    huff -d zip unzipped .... ca serait cool ca non ???? FACILE !!! lol

  9. #49
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    bon voila ca sera mon dernier post avant possible réponse parce que la je comprends plus ...

    le bug je l'ai finalement reglé en remettant a 0 les frequences des codes ASCII de 0 a 8 car ces caracteres ne sont apperement jamais présents dans un texte et ca buggait a ce niveau.

    maintenant mes tab_freq et mes arbres sont bien identiques ...

    mais voila j'ai tjs des petits bugs et la ca va etre beaucoup plus dur a régler ....

    je te poste un texte avant et apres compresssion, si ta une idée .....

    merci d'avance

    http://pyts01.free.fr/text

    http://pyts01.free.fr/unzipped

  10. #50
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Au vu des erreurs qui se sont glissées dans le texte décompressé (n'utilise pas le terme "dézippé", ce n'est pas le même algo), on dirait que tu as :
    1) Un problème avec les caractères >128, ce qui veut donc dire que tu as laissé, quelque part, des "char" au lieu de mettre des "unsigned char".
    2) Le problème étant partiel, il est fort probable que ta table des fréquences soit mal stockée et/ou mal recalculée.
    3) Au vu de la fonction "bin_int", une erreur d'écriture dans le flux compressé est fort problable.

    A ce sujet, je trouve ta fonction bin_int excessivement complexe... Utilisation de "tags" qui peuvent induire des effets de bord, utilisation de fonction "puissance" au lieu des décalages binaires, etc... Bref, c'est ce que l'on appelle habituellement une usine à gaz !!

    Les fonctions que je t'ai données à mon précédent post "planquent" la structure de bits du fichier, et mis à part les tests sur fread/fwrite, elles sont fonctionnelles... Elles te permettent de lire et d'écrire des bits au lieu d'octets, ce qui est le résultat attendu, non ? En plus, elles sont encore largement optimisables, ce qui te laisse de la latitude sur le sujet.

    Enfin, c'est toi qui voit.

    Quant au coup de remettre la fréquence du caractère 0 à zéro manuellement, tu vas faire quoi, le jour où tu vas essayer de compresser du binaire ??? Tu as une erreur qui ressemble fort à un effet de bord, il faut impérativement que tu trouves pourquoi, et pas "patcher" sauvagement... Déjà, en commençant par correctement initialiser ta table des fréquences initiales. Ensuite, on dirait que tu as passé ta table des fréquences à une fonction inadéquate, puisque seul le début de la table est touché => tu as certainement soit un débordement de tableau, soit une mauvaise initialisation d'un autre tableau.

    Perso, j'utilisais les fichiers suivants pour mes jeux de test :
    - Un fichier vide (de zéro octet),
    - Un fichier ASCII en Anglais (env. 100 ko),
    - Un fichier ASCII en Français - avec accents - (env. 100 ko),
    - Un fichier binaire aléatoire (env. 100 ko),
    - Un fichier binaire "lourd" (>25 mégas),
    - Un fichier texte "constant" (ne contenant qu'un seul caractère répété) (env. 100 ko).

    A chaque test, je compressais chaque fichier, puis je le décompressais et j'effectuais une comparaisons octet par octet entre le fichier original et le fichier décompressé (commande DOS "FC /B"). Tu devrais faire de même, tu risques d'avoir de (mauvaises) surprises.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  11. #51
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    en fait je vais te dire la vérité j'ai beaucoup de mal avec le code que tu m'avais posté, j'ai pas du tout l'habitude de manipules ce genre d'opérateurs ( & << !step ????) je comprends pas trop ce qu'ils font

    j'ai pas oublié de char sans unsigned je viens de vérifier....


    cela ne pourrait pas venir du mode d'ouverture des fichier ??????? b ou pas ???

  12. #52
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par ben13
    en fait je vais te dire la vérité j'ai beaucoup de mal avec le code que tu m'avais posté, j'ai pas du tout l'habitude de manipules ce genre d'opérateurs ( & << !step ????) je comprends pas trop ce qu'ils font
    Ce sont les opérateurs de base de manipulation au niveau binaire ou logique. Tout est dans la doc de ton compilateur, normalement (enfin, c'est dans la doc des bons compilateurs).
    & : "AND" ("ET") binaire. Effectue un "ET" binaire (bit à bit) entre les deux opérateurs et retourne le résultat.
    | : "OR" ("OU") binaire. Même syntaxe que &.
    ^ : "XOR" ("OU exclusif") binaire. Même syntaxe que &.
    ! : Négation logique. Vaut "VRAI" si l'argument est nul, et "FAUX" sinon. L'expression "if (!Step)" est équivalente à "if (Step==0)".
    ~ : Négation binaire. Aussi appelé "Complément à 1" ou "NOT" binaire.
    << : Décalage binaire à gauche. "a<<n" est équivalent multiplier "a" par "2 puissance n".
    >> : Décalage binaire à droite. Comme "<<", mais c'est une division au lieu d'une multiplication.
    Tu as encore les opérateurs "&&", "||" et "^^", qui sont respectivement un AND, un OR et un XOR au niveau logique et non pas binaire.
    Jette un oeil sur ta documentation C, sur le rôle et le fonctionnement de tous ces opérateurs.

    Tout ça sont des bases de calcul binaire, et sont souvent extrêmement fréquentes dans les programmes C, surtout s'ils sont axés "bas niveau".

    Citation Envoyé par ben13
    cela ne pourrait pas venir du mode d'ouverture des fichier ??????? b ou pas ???
    Bien sûr qu'ils doivent être ouvert en binaire... Tous les fichiers que tu vas manipuler doivent être ouverts en binaire !!
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  13. #53
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    ok merci je verifie pour le binaire et puis je jetterai un coup d'oeil plus précis a ton code mais c'est vrai que j'aime pas du tout copier des codes... mais c'est que que si j'arrive à comprendre parfaitement ton code je pourrai le réécrire a ma facon et la je dis pourquoi pas ? lol


    merci encore pour ton aide

  14. #54
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    j'ai mis toutes mes ouvertures en binaires et apparement ya moins d'erreurs.

    apperement les erreurs surviennent surtout (voire uniquement) sur les chiffres ...

    une autre question qui me turlupine, je cree sous linux un fichier texte, je colle mon texte dedans, puis je le compresse. a la sortie mon fichier texte source n'est plus reconnu comme fichier texte par l'OS et encore moins mon fichier décompressé ...

    c'est normal docteur ?


    update : j'ai compréssé puis décompressé mon huff.c (6358 octets)

    je l'ai bien parcouru et j'ai relévé 4 erreurs (c pas énorme vu la taille du fichier...)

    voila la liste des "transformations" :

    S --> \
    \n --> M2
    è --> 8
    k; --> {]e'tab'

    il est a noté que chacune de ces erreurs ne se produit qu'une seule fois, et que les caractères ou suite de caractéres S,\n,è et k; n'apparaissent qu'une fois dans le texte original (donc 0 dans le final)


    si ca peut t'aider .....

  15. #55
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par ben13
    ok merci je verifie pour le binaire et puis je jetterai un coup d'oeil plus précis a ton code mais c'est vrai que j'aime pas du tout copier des codes... mais c'est que que si j'arrive à comprendre parfaitement ton code je pourrai le réécrire a ma facon et la je dis pourquoi pas ?
    Comme je te l'ai dit, ce sont tout de même des opérations et des notations plus que fréquentes en C : il est important, si tu envisages de continuer dans la programmation, de bien comprendre comment fonctionnent ces opérations binaires et ce qu'est réellement un booléen pour un ordinateur. Tout ça, ce sont des bases.
    Quant à copier du code, je peux comprendre ta réticence à ce sujet. Par contre, il est anormal (voire inquiétant vis-à-vis de la suite de tes études ou de ta carrière) de ne pas chercher à comprendre un code que tu n'as pas immédiatement saisi. Que feras-tu lorsqu'en entreprise, on te filera un code déjà écrit que tu devras améliorer ou corriger ? Ne rêves pas, tu n'auras pas la possibilité (ni le temps) de le réécrire, il faudra le comprendre, l'assimiler et faire ce qu'il y a à faire dessus, de préférence dans l'esprit du développeur initial en plus...
    Bref, prends tes cours, tes bouquins de C et potasse sur le sujet. Le code que je t'ai donné est franchement très, très simple.

    Citation Envoyé par ben13
    j'ai mis toutes mes ouvertures en binaires et apparement ya moins d'erreurs.
    Ca, ce n'est pas une solution correcte : il ne devrait plus y en avoir du tout. S'il en reste, c'est un problème de table de fréquence (calcul, stockage ou relecture), de construction d'arbre (séparabilité des codes ou calcul des sommes des occurrences) ou de lecture/écriture du flux compressé.

    Citation Envoyé par ben13
    apperement les erreurs surviennent surtout (voire uniquement) sur les chiffres ...
    Ce n'est pas significatif, les codes ASCII des chiffres n'ont rien de particulier. Ca pourrait se produire n'importe où ou presque.
    As-tu vérifié les assignations des tableaux, les parcours, les débordements potentiels ? Utilise les assertions à outrance s'il le faut pour tracer le code à l'exécution, et utilise un débugger pour tracer ton code.
    Pense aussi à sortir la liste des codes de Huffman générés par ta table de fréquence, celle calculée et celle relue depuis le fichier compressé.

    Citation Envoyé par ben13
    une autre question qui me turlupine, je cree sous linux un fichier texte, je colle mon texte dedans, puis je le compresse. a la sortie mon fichier texte source n'est plus reconnu comme fichier texte par l'OS et encore moins mon fichier décompressé ...
    Tu as certainement "écrit" dans ton fichier source, ou tu as interprété les caractères de contrôle (ceux entre 0 et 31 inclus, notamment "\n").

    Citation Envoyé par ben13
    je l'ai bien parcouru et j'ai relévé 4 erreurs (c pas énorme vu la taille du fichier...)
    Comme je te l'ai dit, une c'est déjà trop, quelle que soit la taille initiale du fichier. La moindre erreur signifie que tu n'as pas correctement implémenté l'algo de Huffman, soit au stade de la compression, soit au stade de la décompression. Vu ta fonction "bin_int", la phase de stockage/relecture du fichier compressé peut également être mise en doute.

    Citation Envoyé par ben13
    il est a noté que chacune de ces erreurs ne se produit qu'une seule fois, et que les caractères ou suite de caractéres S,\n,è et k; n'apparaissent qu'une fois dans le texte original (donc 0 dans le final)
    Ce n'est pas significatif, à l'exception unique du fait que tu as des transformations "un caractère -> plusieurs caractères" : ça, ça veut dire que tes codes de Huffman ne sont pas correctement séparés, donc que l'arbre n'est pas correctement construit.

    Tu devrais franchement envisager de faire des tests unitaires de tes fonctions, car il semble que tu aie des erreurs à plusieurs endroits simultanément. Il te faut également vérifier tes invariants en début et fin des fonctions (utilise les assertions pour ça), car il est possible que ton arbre soit corrompu pendant la décompression, entraînant ainsi des erreurs même si l'arbre "initial" était correct.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  16. #56
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    Merci pour toutes tes reponses

    Les booléens je connais tres bien et je sais comment ca se comporte ce qu'on fait en maths discretes par exemple c'est pas d'un niveau de merde .... (c meme la misere lol), c juste que j'avais jamais travaillé avec ca en C. C'est la 1ere année ou je fais du C alors ....

    Sinon effectivement c'est surement un prob de separabilité des codes mais j'avais confiance en mon arbre, en principe la structure de tas evite les redondances je comprends pas trop a quel niveau ca peut foirer.

    J'analyserai ton code un des ces 4 mais comme je t dis ca fait seulement 3 mois que je fais du C alors j'ai pas une connaissance exhaustive sur ce langage...

    Pour les débordements j'aurai surement des erreurs de segmentation vu que mes tableaux ne sont pas dynamiques dans ce programme enfin c'est sur que ya un réel prob, c'est pas normal que la tab de frequences soit différent apres ouverture a partir du fichier compressé ...

    Je vais essayer de me demerder et si j'ai un prob avec ton code je te le dirais ...

    Merci encore a+

  17. #57
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    au fait :

    Tu as certainement "écrit" dans ton fichier source, ou tu as interprété les caractères de contrôle (ceux entre 0 et 31 inclus, notamment "\n").
    je peux pas avoir ecrit dans le fichier source (mode lecture uniquement oblige) par contre qu'est ce que tu entend par "interpréter" les caracteres entre 0 et 31 ?????

  18. #58
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    je comprends pas mon ami la je suis perdu.

    comment une fonction peut modifier une valeur d'un tableau declaré en variable dans le main, sachant qu'elle ne recoit pas ce tableau en argument et qu'il n'est evidement jamais mentionné dans cette fonction..

    je suis SUR que cela vient de cette fonction car j'ai fait un affichage de la valeur JUSTE avant et JUSTE apres.

    la toutes mes croyances s'envolent !!!!!


    a propos, dans ton arbre a toi, tu mettais quoi comme caractere pour les noeud qui ne sont pas des feuilles ??? moi j'ai mis le caractere de code 0 mais j'evite la confusion en testant, quand je parcours l'arbre, si le noeud est une feuille ou non, mais ptet que j'ai oublié un test quelque part et que ca pourrais regler le prob ... ta mis quoi toi ???

  19. #59
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    [Note: Pense à éditer tes messages, le temps de répondre, j'ai pris 2 posts de plus !!!]

    Citation Envoyé par ben13
    Merci pour toutes tes reponses
    Pas de quoi.

    Citation Envoyé par ben13
    Les booléens je connais tres bien
    Je ne parle pas de booléens, là, mais de binaire : ce n'est pas tout à fait la même chose... Tu as plusieurs tutoriels sur le sujet sur ce site, je te conseille d'aller bouquiner tout ça.
    Voici des liens sur ces tutos :
    http://c.developpez.com/faq/c/?page=...ift_left_right
    http://c.developpez.com/faq/c/?page=...URS_amper_mask
    http://c.developpez.com/faq/c/?page=...Unaire_Binaire
    http://rmdiscala.developpez.com/cour...s1/Chap1.3.htm
    Digère tout ça, et tu vas voir que c'est pas franchement compliqué...

    Citation Envoyé par ben13
    C'est la 1ere année ou je fais du C alors ....
    Justement : si tu as bien saisi la manipulation de nombres binaires, le langage, tu t'en contrefous, c'est toujours la même chose (et, heureusement, le même résultat !! ;-)).

    Citation Envoyé par ben13
    Sinon effectivement c'est surement un prob de separabilité des codes mais j'avais confiance en mon arbre, en principe la structure de tas evite les redondances je comprends pas trop a quel niveau ca peut foirer.
    La structure de tas, éviter la redondance ?? En quel honneur ?
    La construction des codes de Huffman obéit à une structure parfaitement définie et rigide, qui consiste à classer les fréquences par ordre décroissant, et à chaque itération, à sommer puis reclasser les deux fréquences les plus faibles. Chaque itération permet de construire un arbre, dont le parcours donne les codes de Huffman.
    Une variante existe (algo de Shannon-Fano), qui permet d'aboutir à un code séparable d'un seul bit pour le caractère le plus fréquent (j'en ai parlé dans un post précédent, je crois). Mais ça suit le même principe de toutes façons.

    Citation Envoyé par ben13
    J'analyserai ton code un des ces 4 mais comme je t dis ca fait seulement 3 mois que je fais du C alors j'ai pas une connaissance exhaustive sur ce langage...
    Là, ce n'est pas un problème de langage, comme je te l'ai précisé, mais un problème de base de numérotation... Bref, c'est des maths et de la logique, pas du C.

    Citation Envoyé par ben13
    Pour les débordements j'aurai surement des erreurs de segmentation vu que mes tableaux ne sont pas dynamiques dans ce programme enfin c'est sur que ya un réel prob, c'est pas normal que la tab de frequences soit différent apres ouverture a partir du fichier compressé ...

    Non, tu n'auras pas forcément une erreur de segmentation, bien au contraire !! C'est justement un des principaux problème du C... Tu peux déborder sur quasiment n'importe quelle variable : du moment que tu ne sors pas de l'espace d'adressage du processus, ça ne provoque pas de GPF/SegFault... Et c'est pire avec les tableaux non-dynamiques, car ils sont en plus contigüs en mémoire. Vérifie quelles sont les variables déclarées juste avant ton tableau de fréquence : s'il y a débordement, c'est certainement une de celles-ci qui est fautive.

    Citation Envoyé par ben13
    Je vais essayer de me demerder et si j'ai un prob avec ton code je te le dirais ...
    OK.

    Citation Envoyé par ben13
    je peux pas avoir ecrit dans le fichier source (mode lecture uniquement oblige)
    S'il n'est plus reconnu comme fichier texte, c'est bien qu'il a été modifié, non ? Vérifie avec une copie de secours, et compare octet par octet les deux fichiers, en mode binaire... Sous DOS/Windows, c'est la commande "FC /B Fichier1 Fichier2" qui fait ça, je ne connais pas son équivalent Unix.

    Citation Envoyé par ben13
    par contre qu'est ce que tu entend par "interpréter" les caracteres entre 0 et 31 ?????
    Ce sont des caractères de contrôle. Par exemple, le caractère 0x07 fait un "bip" si tu essaie de l'afficher. Si tu lis (ou écrit) ces caractères avec des fonctions de manipulation de chaîne et/ou vers/depuis les consoles, tu risques d'avoir des problèmes : c'est pour ça qu'il faut lire ces caractères en mode binaire exclusivement pour ce genre d'application.

    Citation Envoyé par ben13
    comment une fonction peut modifier une valeur d'un tableau declaré en variable dans le main, sachant qu'elle ne recoit pas ce tableau en argument et qu'il n'est evidement jamais mentionné dans cette fonction..
    Bienvenue dans le monde du C... Ton tableau dans ton "main" est dans l'espace d'adressage du processus, donc il est modifiable (par erreur la plupart du temps, heureusement) par n'importe quelle fonction de ton programme sans contrôle possible ni du compilateur, ni de la CLib... C'est pas du Pascal/Delphi ou de l'ADA !!
    Examine attentivement ta fonction (ou poste-là, avec les déclarations de variables qu'elle utilise), et tu vas voir que soit elle déborde de manière "visible", soit qu'il y a un effet de bord que tu n'as pas examiné. Va voir du côté des assertions pour "blinder" ton code, ça te sera très utile.
    http://smeric.developpez.com/java/astuces/assertions/
    C'est du Java, mais le principe y est expliqué. En C, la fonction est "assert()", elle est déclarée dans "assert.h" si ma mémoire est bonne (=> cf. doc de ton compilateur de toutes façons).
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  20. #60
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 63
    Points : 6
    Points
    6
    Par défaut
    voila, je te poste les declarations de struct et de var globale, la fonction accusée et le main. tu vas dire que c'est une usine a gaz en chantier je comprends mais c'est pas pour ca que ca doit bugger.

    ps : c est declaré en var globale car javais au debut fait retourner un *CODE a chemin mais ca marchait pas (probablement a cause de la récursivité).

    j'ai marqué a quel moment du main tab_freq[0] est modifié, c'est dans la boucle for

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    # include <stdio.h>
    # include <string.h>
    # include <stdlib.h>
    # include <stddef.h>
    # include <math.h>
     
    # define N 256
    # define M 8
     
    /*Les maillons "sommes" ont pour caractere le code ASCII 0 : caractere NULL*/
     
     
     
    typedef struct noeud *ARBRE;
    struct noeud
    {
    	unsigned char  e;
    	int frequence;
    	ARBRE fg, fd; 
    };
     
     
    typedef struct
    {
    	unsigned char taille_code;
    	unsigned char code[M];
    }CODE;
     
     
    CODE *c;
     
     
     
    /*Fonction recursive calculant le chemin binaire d'un caractere, c (pointeur sur une struct CODE) variable globale*/
    void chemin ( unsigned char e, ARBRE t, unsigned char prefixe[M], unsigned char taille_pref ){
     
    	int i;
    	CODE* tmp;
     
    	tmp = malloc(sizeof(CODE));
     
    	if ( (t->e == e) && (t->fg == NULL) && (t->fd == NULL) ){
    		tmp->taille_code = taille_pref;
     
    		for (i=0;i<taille_pref;i++)
    			tmp->code[i] = prefixe[i];
     
    		for (i=taille_pref;i<M;i++)/*initialise les cases non utilisées du tableau code à 0*/
    			tmp->code[i] = 0;
     
    		c = tmp;
    	}
     
    	else {
    		if ( t != NULL ){
     
    			if ( t->fg != NULL ) {
    				prefixe[taille_pref] = 0;
    				chemin ( e, t->fg, prefixe, taille_pref+1 );
    			}
     
    			if ( t->fd != NULL ) {
    				prefixe[taille_pref] = 1;
    				chemin ( e, t->fd, prefixe, taille_pref+1 );
    			}
     
    		}
     
    	}
     
    }
     
     
     
    main(){
    	unsigned char tampon[N], tampon2[N];
    	int tab_freq[N];
    	unsigned char prefixe[M],taille_pref;
    	int i, j, taille_file;
    	ARBRE file [N];
    	ARBRE t;
    	CODE *tab_codes[N];
    	unsigned char tab_codes_comp[2*N];
     
    	FILE *dest, *source;
     
    	/*Ouverture fichier source*/
    	printf("Emplacement du fichier à compresser: ");
    	scanf("%s",tampon);
    	source = fopen ( tampon, "rb" );
     
    	/*Ouverture fichier destination*/
    	printf("Nom fichier compressé : ");
    	scanf("%s",tampon2);
    	dest = fopen(tampon2,"wb");
     
    	frequence ( tampon, tab_freq );
     
    	fwrite ( tab_freq, 1024, 1, dest);
     
    	taille_file = construire_file(file,tab_freq);
     
    	t = huffman(file,taille_file);
     
     
     
     
     
    	/*Boucle qui remplit le tableau tab_codes avec : Caractere/taille_code/code*/
    	for(i=0;i<N;i++){
    		taille_pref = 0;
    		c = NULL;
    		chemin ( i, t, prefixe, taille_pref );/*le 1er appel de chemin (i=0) modifie tab_freq[0] !!! */
    		printf("%d\n",tab_freq[0]);
    		tab_codes[i] = c;
    	}
     
     
    	compression ( source, tab_codes );
     
    	bin_int ( fopen ( "~tmpcomp", "rb" ), dest );
     
    	fclose(dest);
     
    	fclose(source);
     
     
    }
    a propos, dans ton arbre a toi, tu mettais quoi comme caractere pour les noeud qui ne sont pas des feuilles ??? moi j'ai mis le caractere de code 0 mais j'evite la confusion en testant, quand je parcours l'arbre, si le noeud est une feuille ou non, mais ptet que j'ai oublié un test quelque part et que ca pourrais regler le prob ... ta mis quoi toi ???

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Remplir un fichier binaire à partir d'une image
    Par my_account dans le forum C
    Réponses: 5
    Dernier message: 10/12/2011, 16h17
  2. impossible de remplir une structure à partir d'un fichier binaire
    Par étoile de mer dans le forum Débuter
    Réponses: 3
    Dernier message: 21/12/2009, 12h28
  3. Fichiers binaires et machine 32 ou 64 bits
    Par genteur slayer dans le forum Fortran
    Réponses: 5
    Dernier message: 10/03/2009, 17h23
  4. Ecrire dans un fichier binaire en inversant les poids des bits
    Par zejo63 dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 09/07/2007, 15h11
  5. Réponses: 5
    Dernier message: 03/06/2005, 14h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo