Znalazłem taki kod w internecie:
/*************************** BIBLIOTHEQUE ***************************/
#include <iostream.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
/***************************** FICHIERS *****************************/
FILE *fic_lec;
FILE *fic_ecr;
/************************ VARIABLES GLOBALES ************************/
int tab_occ[256][256];
int aux[256];
int arbre_code[64];
int bin[7];
int cpt_arbre_code = -1;
int nb_char_dif = 0;
char fi[40];
char f1[40];
char f2[40];
unsigned long int nb_lettre = 0;
/*********************** STRUCTURE DE L ARBRE ***********************/
struct pointeur
{
int c;
int nb;
pointeur *suivant;
pointeur *fg;
pointeur *fd;
};
/*********************** STRUCTURE DE LA PILE ***********************/
struct pile
{
int prof;
pointeur *val;
pile *suivant;
};
/************************* SOUS PROGRAMMES **************************/
// Permet d empiler une adresse d arbre et une profondeur
// dans la pile "pile"
void empiler(pile **p,pointeur *arb,int pro)
{
pile *b;
b = new pile;
b->val = arb;
b->prof = pro;
b->suivant = *p;
*p = b;
}
// Retourne l adresse d arbre qui se trouve au sommet
// de la pile "pile"
pointeur *val(pile *p)
{
if (p) return p->val;
else return(NULL);
}
// Retourne la profondeur qui se trouve au sommet
// de la pile "pile"
int prof(pile *p)
{
if (p) return p->prof;
else return(0);
}
// Permet de depiler la pile "pile"
void depiler(pile **p)
{
pile *a;
a = *p;
if (p != NULL)
{
if (a->suivant == NULL) *p = NULL;
else *p = a->suivant;
delete[] a;
}
}
// Permet d ajouter un maillon avec un charactere
// et un nombre d occurence dans la liste chainee
void ajout(pointeur **point,int x,int y)
{
pointeur *p, *q;
q = new pointeur;
q->c = y;
q->nb = x;
p = *point;
if ((!p) || (p->nb > x))
{
q->suivant = *point;
*point = q;
}
else
{
while ((p->suivant != NULL) && (p->suivant->nb < x)) p = p->suivant;
q ->suivant = p->suivant ;
p->suivant = q;
}
}
// Permet d ajouter un maillon avec une adresse d arbre
// dans la liste chainee
void ajout_ptr(pointeur **point,pointeur *ptr)
{
pointeur *p;
p = *point;
if (!p)
{
ptr->suivant = *point;
*point = ptr;
}
else
{
while ((p->suivant != NULL) && (p->suivant->nb < ptr->nb)) p = p->suivant;
ptr->suivant = p->suivant ;
p->suivant = ptr;
}
}
// Permet d effectuer 2^i
int expo(int h,int i)
{
int nb = 1;
for (int j = 0;j < i;j++) nb = h * nb;
return nb;
}
// Permet de construire l arbre a partir de la liste chainee
// des occurences d apparition des lettres du fichier triee
// dans l ordre croissant
void construction_arbre(pointeur **arbre)
{
pointeur *p ,*q;
p = *arbre;
if (p->suivant != NULL)
{
while (1)
{
q = new pointeur;
q->nb = p->nb + p->suivant->nb; q->c = -1;
q->fg = p; q->fd = p->suivant;
p = p->suivant->suivant;
ajout_ptr(&p,q);
if (p->suivant == NULL) break;
}
}
else
{
q = new pointeur;
q->nb = p->nb; q->c = -1;
q->fg = p;
ajout_ptr(&p,q);
}
*arbre = p;
}
// Remplis la matrice de correspondance "tab_occ"
// comportant les nouveaux code de chaque lettre
// et code l arbre avec des 0 et des 1 dans
// le tableau "arbre_code"
void correpondance_code(pointeur *p)
{
pile *pile = NULL;
int cpt_aux = 0;
int cpt_arbre = 7;
int nb = 0;
while (1)
{
if (p->c == -1) // Si ce n est pas une feuille
{
empiler(&pile,p,cpt_aux); // Parcours
p = p->fg; // de l arbre
nb = nb + 1 * expo(2,cpt_arbre); // Construction
cpt_arbre--; // de l arbre
aux[cpt_aux] = 0; // Nouveau code
cpt_aux++; // de la lettre
}
else // Si c est une feuille
{
// Transfert le tableau "aux" a la ligne
// de la matrice "tab_occ" correspondante
for (int ecr_aux = 0;ecr_aux < cpt_aux;ecr_aux++)
tab_occ[p->c][ecr_aux] = aux[ecr_aux];
tab_occ[p->c][cpt_aux] = '/0'; // Fin du nouveau code
nb_char_dif--; // Si tout les caracteres
if (nb_char_dif == 0) break; // ont ete traites sortir
p = val(pile); //
cpt_aux = prof(pile); // Parcours de l arbre
depiler(&pile); //
p = p->fd; //
aux[cpt_aux] = 1; // Initialisation code
cpt_aux++; // dans un tableau "aux"
cpt_arbre--; // Construction de l arbre
}
if (cpt_arbre == -1) // Si code de la arbre contient 8 bits
{
cpt_arbre_code++; //
arbre_code[cpt_arbre_code] = nb; // Ecriture de la
nb = 0; // forme de l arbre
cpt_arbre = 7; //
}
}
cpt_arbre_code++; // Ecriture de la
arbre_code[cpt_arbre_code] = nb; // forme de l arbre
}
// Parcours de l arbre en recursif et ecriture
// dans le fichier des lettres dans les feuilles
void ecriture_lettre(pointeur *p,int j)
{
if (j == -1) p = p->fg;
if (j == 1) p = p->fd;
if (p->c == -1)
{
ecriture_lettre(p,-1);
ecriture_lettre(p,1);
}
else fprintf(fic_ecr,"%c",p->c);
}
int val(int i)
{
if (i == 7) return 128;
if (i == 6) return 64;
if (i == 5) return 32;
if (i == 4) return 16;
if (i == 3) return 8;
if (i == 2) return 4;
if (i == 1) return 2;
if (i == 0) return 1;
return 0;
}
// Ecriture du nouveau code avec une re-lecture du fichier
// en ecrivant le nouveau code correspondant a chaque lettre dans
// un buffer intermediaire "nb" (sous forme decimale)
// comportant 8 bits
void nouveau_code()
{
int lettre;
int i = 7;
int j = 0;
int nb = 0;
while (!feof(fic_lec))
{
lettre = fgetc(fic_lec);
if (feof(fic_lec))
{
fprintf(fic_ecr,"%c",nb);
break;
}
while (tab_occ[lettre][j] != '/0')
{
// nb = nb + tab_occ[lettre][j] * pow(2,i);
nb = nb + tab_occ[lettre][j] * val(i);
// nb = nb + tab_occ[lettre][j] * expo(2,i);
if (i == 0)
{
fprintf(fic_ecr,"%c",nb);
i = 8;
nb = 0;
}
i--;
j++;
}
j = 0;
}
}
// Compression du fichier f1 dans la fichier f2
void compression()
{
int aux;
int cpt_dec = 0;
cout<<"Rentrer le nom du fichier ŕ Compresser"<<endl;
cout<<"Le chemin Complet : ";
cin>>fi;
strcpy(f1,fi);
strcpy(f2,fi);
strcat(f2,".jmp");
printf("COMP");
fic_lec = fopen(f1,"rb");
while (!feof(fic_lec)) //
{ //
tab_occ[fgetc(fic_lec)][0]++; // Construction du
nb_lettre++; // tableau d occurence
} //
nb_lettre--;
fclose(fic_lec);
pointeur *arbre = NULL;
for (int cpt1 = 0;cpt1<256;cpt1++) //
{ // Construction de
if (tab_occ[cpt1][0] != 0) // la liste chainee
{ // avec le tableau
ajout(&arbre,tab_occ[cpt1][0],cpt1); // d occurence triee
nb_char_dif++; // dans l ordre
} // croissant
} //
fic_lec = fopen(f1,"rb"); // Ouverture du fichier en lecture
fic_ecr = fopen(f2,"wb"); // Ouverture du fichier en ecriture
if (nb_lettre != 0) // Si le fichier n est pas vide
{
printf("R");
construction_arbre(&arbre);
printf("E");
correpondance_code(arbre);
printf("S");
// Ecriture du nombre d octet sur lequel est code l arbre
// et ecriture de tout les octets correspondant a l arbre
fprintf(fic_ecr,"%c",cpt_arbre_code);
for (int ecr_arb = 0;ecr_arb <= cpt_arbre_code;ecr_arb++)
fprintf(fic_ecr,"%c",arbre_code[ecr_arb]);
ecriture_lettre(arbre,0);
aux = nb_lettre;
while (aux/10 != 0)
{
cpt_dec++;
aux = aux/10;
}
// Ecriture du nombre d octet sur lequel est compris
// le nombre de lettre
// et ecriture du nombre de lettre
fprintf(fic_ecr,"%c",cpt_dec+1);
fprintf(fic_ecr,"%d",nb_lettre);
nouveau_code();
printf("SION");
}
else printf("RESSION");
fclose(fic_lec);
fclose(fic_ecr);
cout<<"\nle fichier a ete correctement Compresse";
cout<<"\nIl se trouve dans : "<<f2<<endl;
}
// Permet de transformer un nombre decimale
// en binaire dans le tableau "bin"
void dec_bin(int dec)
{
for(int i = 7;i >= 0;i--)
{
// bin[7-i] = dec / expo(2,i);
// dec = dec % expo(2,i);
bin[7-i] = dec / val(i);
dec = dec % val(i);
}
}
// Re-ecriture a chaque feuille de l arbre
// des lettres correspondantes dans le fichier
void lettre(pointeur *p,int j)
{
if (j == -1) p = p->fg;
if (j == 1) p = p->fd;
if (p->c == -1)
{
lettre(p,-1);
lettre(p,1);
}
else
{
p->c = fgetc(fic_lec);
}
}
// Reconstruction de l arbre a l aide du code
// dans le fichieret une pile "pile"
void reconstruction(pointeur **ptr,int q)
{
pointeur *p;
pile *pile;
p = *ptr;
for (int i = 0;i <= q;i++)
{
if (arbre_code[i] == 1)
{
p->c = -1;
pointeur *ptr1, *ptr2;
ptr1 = new pointeur;
ptr2 = new pointeur;
p->fg = ptr1;
p->fd = ptr2;
empiler(&pile,p->fd,0);
p = p->fg;
}
if (arbre_code[i] == 0)
{
p = val(pile);
depiler(&pile);
}
}
}
// Ecriture de chaque lettre en parcourant l arbre
void ecriture(pointeur *arbre)
{
pointeur *a;
int cpt;
a = arbre;
while (!feof(fic_lec))
{
dec_bin(fgetc(fic_lec));
cpt = 0;
while ((cpt < 8) && (nb_lettre > 0))
{
while (a->c == -1)
{
if (bin[cpt] == 0) a = a->fg;
if (bin[cpt] == 1) a = a->fd;
cpt++;
if (cpt == 8) break;
}
if (cpt == 8) break;
fprintf(fic_ecr,"%c",a->c);
if (a->c != -1) a = arbre;
nb_lettre--;
}
}
}
// Decompression du fichier f1 dans le fichier f2
void decompression()
{
int cpt_dec = 0;
int taille_arbre_code;
cout<<"Rentrer le nom du fichier a décompresser"<<endl;
cout<<"Le chemin Complet, sans l'extension .jmp : ";
cin>>fi;
strcpy(f1,fi);
strcat(f1,".jmp");
cout<<"Fichier de Destination : ";
cin>>fi;
strcpy(f2,fi);
fic_lec = fopen(f1,"rb");
cpt_arbre_code = fgetc(fic_lec);
printf("DE");
for (int x = 0;x <= cpt_arbre_code;x++)
{
dec_bin(fgetc(fic_lec));
for (int y = 0;y <= 7;y++)
arbre_code[8*x+y] = bin[y];
}
taille_arbre_code = (8*cpt_arbre_code+8)-1;
while (arbre_code[taille_arbre_code] != 1) taille_arbre_code--;
pointeur *arbre = NULL;
arbre = new pointeur;
reconstruction(&arbre,taille_arbre_code);
lettre(arbre,0);
fic_ecr = fopen(f2,"wb");
cpt_dec = fgetc(fic_lec) - 1;
nb_lettre = 0;
while (cpt_dec >= 0)
{
nb_lettre = nb_lettre + (fgetc(fic_lec) - 48) * expo(10,cpt_dec);
cpt_dec--;
}
printf("COMP");
ecriture(arbre);
printf("RESSION");
fclose(fic_lec);
fclose(fic_ecr);
cout<<"\nle fichier a ete correctement decompresse";
cout<<"\nIl se trouve dans : "<<f2<<endl;
}
void menu()
{
cout<<"+------------------------------------------------+\n";
cout<<"| |\n";
cout<<"| Menu General : |\n";
cout<<"| |\n";
cout<<"| 1) Compression d un Fichier |\n";
cout<<"| 2) Decompression d un fichier |\n";
cout<<"| |\n";
cout<<"| 0) Quitter |\n";
cout<<"| |\n";
cout<<"+------------------------------------------------+\n";
}
void Presentation()
{
cout<<" Algorithme de Compression de Huffman"<<endl;
}
int main()
{
char choix;
Presentation();
do
{
menu();
cout<<"Votre choix : ";
cin >> choix;
switch (choix)
{
case '1':
compression();
break;
case '2':
decompression();
break;
};
}while (choix != '0');
}
Jednak po kompilacji w Dev C++ nie działa - po podaniu pliku do kompresji program się zawiesza... - wie ktoś gdzie tu jest błąd ?
Z góry dzięki za odpowiedź.