Guillaume - Update Gestion Fichiers

This commit is contained in:
name 2019-12-14 11:10:02 +01:00
parent 91c2bb9660
commit 71980e4541
No known key found for this signature in database
GPG key ID: 03E8F3CF3183323A
7 changed files with 191 additions and 393 deletions

View file

@ -1,126 +0,0 @@
#include <assert.h>
#include <stdlib.h>
#include "liste.h"
Freq creer_liste_vide(){
return NULL;
}
int est_liste_vide(Freq l){
return(l==NULL);
}
Freq ajouter(int nb, int lettre, Freq l){
Occ * tmp;
tmp=malloc(sizeof(Occ));
tmp->nb=nb;
tmp->lettre=lettre;
tmp->suiv=l;
return tmp;
}
Freq inserer(Occ *place, Freq l){
printf(" Inserer :\n");
if(est_liste_vide(l)){
printf(" Liste vide :\n");
return ajouter(place->nb,place->lettre,creer_liste_vide());
}
else{
printf(" Liste non vide :\n");
Occ * tmp;
tmp = l;
if(tmp->suiv == NULL){
if(tmp->nb < place->nb){
tmp->suiv=place;
place->suiv=NULL;
}else{
place->suiv=tmp;
l=place;
}
return l;
}
while(tmp->suiv != NULL){
if(tmp->suiv->nb >= place->nb){
place->suiv=tmp->suiv;
tmp->suiv=place;
return l;
}
else{
tmp=tmp->suiv;
}
}
// Ajoute à la fin
while(l->suiv != NULL){
l = l->suiv;
}
l->suiv=place;
return l;
}
}
int tete_lettre(Freq l){
assert(!est_liste_vide(l));
return(l->lettre);
}
int tete_freq(Freq l){
assert(!est_liste_vide(l));
return(l->nb);
}
Freq queue(Freq l){
assert(!est_liste_vide(l));
return(l->suiv);
}
void liberer_liste(Freq l){
if(!est_liste_vide(l)){
liberer_liste(queue(l));
free(l);
}
}
Freq liberer_maillon(Freq l){
assert(!est_liste_vide(l));
Occ * tmp = l->suiv;
free(l);
return tmp;
}
int liste_rechercher(int lettre,Freq l){
if(est_liste_vide(l)){
return 0;
}
else if(lettre==tete_lettre(l)){
return 1;
}
else{
return liste_rechercher(lettre,queue(l));
}
}
Freq incrementer(int lettre, Freq l){
/*
Incrémente de 1, l'occurence de la lettre associée
(Attention ! Ici, la liste est parcourue complétement même si on a déjà incrémenté ... Autres solutions ?)
*/
if(est_liste_vide(l)){
return l;
}
else{
while(lettre != tete_lettre(l)){
l=queue(l);
}
l->nb++;
return l;
}
}
void afficher(Freq L){
printf("Affichage ...\n");
while(queue(L) != NULL){
printf(" P : %d | Char : %d\n",tete_freq(L),tete_lettre(L));
L=queue(L);
}
printf("Fin Affichage.\n");
}

View file

@ -1,23 +0,0 @@
#ifndef __LISTE_OCCURENCE__
#define __LISTE_OCCURENCE__
struct zoccurence{
int nb;
int lettre;
struct zoccurence *suiv;
};
typedef struct zoccurence Occ;
typedef struct zoccurence * Freq;
Freq creer_liste_vide();
int est_liste_vide(Freq l);
Freq ajouter(int nb, int lettre, Freq l);
Freq inserer(Occ *place, Freq l);
int tete_lettre(Freq l);
int tete_freq(Freq l);
Freq queue(Freq l);
void liberer_liste(Freq l);
Freq liberer_maillon(Freq l);
int liste_rechercher(int lettre, Freq l);
Freq incrementer(int lettre, Freq l);
void afficher(Freq L);
#endif

View file

@ -17,11 +17,11 @@ Bin_file *Ouv_Bit(char *p,char mode)
A->mode=mode; //On récupére le mode d'ouverture du fichier et on le rentre dansle struct A->mode=mode; //On récupére le mode d'ouverture du fichier et on le rentre dansle struct
if(mode=='r') //suivant le mode (écriturer w ou lecture r) on va ouvrir le fichier a l'aide de fopen et on if(mode=='r') //suivant le mode (écriturer w ou lecture r) on va ouvrir le fichier a l'aide de fopen et on
{ //enregistre cela dans lestruct Bin_files { //enregistre cela dans lestruct Bin_files
A->file=fopen(p,"r"); A->file=fopen(p,"rb");
} }
else else
{ {
A->file=fopen(p,"w"); A->file=fopen(p,"wb");
} }
A->record_length=0; //On va ensuite initialiser tous les élèments du struct. A->record_length=0; //On va ensuite initialiser tous les élèments du struct.
A->i_record=0; A->i_record=0;
@ -30,33 +30,33 @@ Bin_file *Ouv_Bit(char *p,char mode)
return A; return A;
} }
void Ec_Bit(Bin_file *output,char bit) // On veux une fonction capable d'écrire un bit dans un fichier void Ec_Bit(Bin_file *output,char bit) // On veux une fonction capable d'écrire un bit dans un fichier
{ {
unsigned char octet,b; // On utilise deux variables octet et b qui vont permettre de récupérer les élèmets a écrire. unsigned char octet,b; // On utilise deux variables octet et b qui vont permettre de récupérer les élèmets a écrire.
int i; int i;
output->octet[output->i_octet]=bit; // On va mettre le premier élèment du tableau octet de la struct Bin_file a la valeur de bit output->octet[output->i_octet]=bit; // On va mettre le premier élèment du tableau octet de la struct Bin_file a la valeur de bit
output->i_octet++; //On incremente aussi i_octet pour ne pas réecrire surcette valeur output->i_octet++; //On incremente aussi i_octet pour ne pas réecrire surcette valeur
if (output->i_octet==8) //Si le tableau octet est plein on va aller écire dans le tableau record if (output->i_octet==8) //Si le tableau octet est plein on va aller écire dans le tableau record
{ {
octet=0; //on passe octet a 0 et b a 0x80 soit 1000 0000 octet=0; //on passe octet a 0 et b a 0x80 soit 1000 0000
b=0x80; // cela permet de toujoursgarder 1 en bit de poids fort dans b apre les décalages a droite b=0x80; // cela permet de toujoursgarder 1 en bit de poids fort dans b apre les décalages a droite
for(i=0;i<8;i++) for(i=0;i<8;i++)
{ {
if(output->octet[i]=='1') //si on a un '1' dans le tableau octet on va mettre dans octet le résultats de octet ou b if(output->octet[i]=='1') //si on a un '1' dans le tableau octet on va mettre dans octet le résultats de octet ou b
{ {
octet=octet|b; octet=octet|b; // On va alors creer une "copie" du tableau octet dans octet
} }
b=b>>1; b=b>>1;
} }
output->i_octet=0; output->i_octet=0;
output->record[output->i_record]=octet; // On va apres le for remmtre i_octet a 0 puis on passe dans record la valeur du char octet pour conserver output->record[output->i_record]=octet; // On va apres le for remetre i_octet a 0 puis on passe dans record la valeur du char octet pour conserver
output->i_record++; //ce que l'on veut écrire output->i_record++; //ce que l'on veut écrire
output->nb_octets++; //On incrémente aussi i record pour passer a l'élèment suivant et nb_octets car on en a traiter un autre output->nb_octets++; //On incrémente aussi i record pour passer a l'élèment suivant et nb_octets car on en a traiter un autre
if(output->i_record==BLOCK_SIZE) //On vérifie ensuite que record qui sert de buffer soit plein avant d'écrire sont contenue. if(output->i_record==BLOCK_SIZE) //On vérifie ensuite que record qui sert de buffer soit plein avant d'écrire sont contenue.
{ {
fwrite(output->record,1,BLOCK_SIZE,output->file); fwrite(output->record,1,BLOCK_SIZE,output->file);
output->i_record=0; //si on éceit on reinitialise i record pour passer auxélèments suivant output->i_record=0; //si on éceit on reinitialise i record pour passer auxélèments suivant
} }
} }
@ -65,67 +65,57 @@ void Ec_Bit(Bin_file *output,char bit) // On veux une f
char Lec_Bit(Bin_file*input) char Lec_Bit(Bin_file*input)
{ {
char bit; //On veut lire un fichier bit a bit. Pourcela on va vérifier si la record length est nul ou non char bit; //On veut lire un fichier bit a bit. Pourcela on va vérifier si la record length est nul ou non
unsigned char x, b=0x80; // Ici on déclare de char, x va permettre de récupérer un octet de record
// b vas servir de masque. Il nous permettra de savoir quelle valeur possède les bits des élèment de record
int i; //i est un compteur utiliser pour les boucles for
if (input->record_length==0) if (input->record_length==0){ // Si le buffer (record),est videon va aller chercher lesélèments du fichier
{
fread(input->record,BLOCK_SIZE,1,input->file); // si il est nul on va aller le fichier
input->record_length=(BLOCK_SIZE/8); //on va rentré la longueur lue (4096 bit) en octet
input->i_record=0; //on reinitialise i_record pour etre sur de reprendre le record du début
for (input->i_octet=0;input->i_octet<8;input->i_octet++) //On va ensuite aller écrire dans le tableau octet. input->record_length = fread(input->record,1,BLOCK_SIZE,input->file); //Pour cela on récupère dans record_length le nombre d'élèment de input-file et on les écrit dans record
{ input->i_record=0; //On réinitialise l'indice de record pour recommencerdepuis le début.
if((input->record[input->i_record]>>1)&1) //pour cela on predre le premier élèment de record le décallé de 1 bit a droite et a chaque décallage on va comparer avec 1
{ x = input->record[input->i_record] ; //On réupère la valeurde record[i_record] dans x
input->octet[7-input->i_octet]='1'; //Si le bit vaut 1 on ajoute '1' a octet, 0 sinon for(i=0;i<8;i++) {
} // cette méthode lisant en premeir les bits de poids faible, on les ajoutes en partant de la fin du tableau. if(x&b) input->octet[i]='1'; //On va alors tester les bits de x grace a x&b. Cela permet de renvoyer 1 si lesdeux bits sont a 1
else else input->octet[i]='0'; // si le test est vrai on ajoute le char 1 dans octet sinon 0
{ b=b>>1; //On décale ensuite b de 1 bit a droite pourconserver le 1 a l'endroit que l'on veut tester
input->octet[7-input->i_octet]='0';
}
} }
input->octet[8]=0; //On passe le derneir élèment de octet a 0 pour marquer la fin de chaine de caractère
input->i_record++; //on incrémente i record pour aller a l'élèment suivant on réinitialise i_octet et input->i_record++; //on incrémente i record pour aller a l'élèment suivant on réinitialise i_octet et
input->i_octet=0; input->i_octet=0;
input->nb_octets=input->nb_octets+input->record_length; input->nb_octets=input->nb_octets+input->record_length; //On ajoute la taille du record dans nb_octets pour conserver le bon nombred'élèment traité
} }
bit=input->octet[input->i_octet]; //On passe alors bit a la valeur de octet[0] bit=input->octet[input->i_octet]; //On passe alors bit a la valeur de octet[0]
input->i_octet++; //on incrémente ensuite le compteur input->i_octet++; //on incrémente ensuite le compteur
if(input->i_octet=8) if(input->i_octet==8){ // Si on a écrit huit bit dans octet on va aller tester l'élèment suivant de record
{ x = input->record[input->i_record] ;
for (input->i_octet=0;input->i_octet<8;input->i_octet++) //Comme précédemment on récupère les 1 et les 0 de record pour les passé dans octet for(i=0;i<8;i++) {
{ if(x&b) input->octet[i]='1';
if((input->record[input->i_record]>>1)&1) else input->octet[i]='0';
{ b=b>>1;
input->octet[7-input->i_octet]='1';
}
else
{
input->octet[7-input->i_octet]='0';
}
} }
input->octet[8]=0;
input->i_record++; input->i_record++;
input->i_octet=0; input->i_octet=0;;
if(input->i_record=BLOCK_SIZE) //si on a parcouru tous le buffer on repasse a 0 la longueur if(input->i_record==BLOCK_SIZE){ //si on a parcouru tous le buffer on repasse a 0 la longueur
{
input->record_length=0; input->record_length=0;
} }
} }
return bit; // on renvoie le bit return bit; // on renvoie le bit
} }
int Ferm_Bit(Bin_file *fichier) int Ferm_Bit(Bin_file *fichier)
{ {
unsigned char octet,b; unsigned char octet,b; // On déclare deux unsigned char octet et b qui auront la même utilité que dans Ec_Bit
int nb_octets=fichier->nb_octets; int nb_octets=fichier->nb_octets;
if(fichier->mode="w") if(fichier->mode="w") // Si le fichier a été ouvert en mode écriture on va aller écrire la fin du buffer
{ { // dans le fichier.
if(fichier->i_octet!=0) if(fichier->i_octet!=0) //Pour cela on répète le même principe que dans Ec_Bit
{ {
octet=0; octet=0;
b=0x80; b=0x80;
@ -147,30 +137,35 @@ int Ferm_Bit(Bin_file *fichier)
fwrite(fichier->record,1,BLOCK_SIZE,fichier->file); fwrite(fichier->record,1,BLOCK_SIZE,fichier->file);
} }
} }
fclose(fichier->file); fclose(fichier->file); //On ferme ensuite le fichier et on libère l'espace occupé par le srtuct Bin_File.
free(fichier); free(fichier);
return nb_octets; return nb_octets;
} }
/*
int main() void main()
{ {
Bin_file *p; Bin_file *p;
char s[16];
int i; int i;
p=Ouv_Bit("test.txt",'r'); p=Ouv_Bit("test.txt",'r');
printf("%d",p->record_length); printf("%i\n",p->record_length);
/* for (i=0;i<16;i++){
for(i=0;i<32762;i++) s[i]=Lec_Bit(p);
{
Ec_Bit(p,'1');
} }
*/ for(i=0;i<16;i++){
for(i=0;i<32762;i++) printf("%c",s[i]);
{
printf("%c",Lec_Bit(p));
} }
int n=Ferm_Bit(p); Ferm_Bit(p);
printf("\n"); p=Ouv_Bit("test.txt","w");
printf("%i\n",n); Ec_Bit(p,'0');
return 0; Ec_Bit(p,'1');
Ec_Bit(p,'1');
Ec_Bit(p,'0');
Ec_Bit(p,'0');
Ec_Bit(p,'1');
Ec_Bit(p,'1');
Ec_Bit(p,'0');
Ferm_Bit(p);
} }
*/

View file

@ -4,18 +4,27 @@
#ifndef __GESTION_FICHIERS__ #ifndef __GESTION_FICHIERS__
#define __GESTION_FICHIERS__ #define __GESTION_FICHIERS__
#include <stdio.h> #include <stdio.h>
#define BLOCK_SIZE 4096 #define BLOCK_SIZE 128 //il faut changer sa valeur pour les tests avec blocsize = nb d'octet qu'on veut écrire
typedef struct typedef struct
{ {
FILE*file; // Identificateur fichier FILE*file; // Identificateur fichier
char mode; // Mode de lecture r ou w char mode; //Mode de lecture r ou w
unsigned char record[BLOCK_SIZE]; // Tampon pour lire ou écrire unsigned char record[BLOCK_SIZE]; //Tampon pour lire ou écrire
int record_length; // nombre d'élèments du tampon int record_length; //nombre d'élèments du tampon
int i_record; // indice dans le tampon int i_record; //indice dans le tampon
char octet[8]; // On découpe l'octet en 8 caractère char octet[9]; //On découpe l'octet en 8 caractère
int i_octet; // indice dansl'octet int i_octet; //indice dansl'octet
int nb_octets; // Nb octet lis/écrit int nb_octets; //Nb octet lis/écrit
}Bin_file; }Bin_file;
Bin_file *Ouv_bit(char *p,char mode);
void Ec_Bit(Bin_file *output,char bit);
char Lec_Bit(Bin_file*input);
int Ferm_Bit(Bin_file *fichier);
#endif #endif

View file

@ -1 +1 @@
AAABBBCCCCCDDDDDD DDDCCCBBBBBAAAAAA

View file

@ -1,3 +0,0 @@
NNN
dede
salut

View file

@ -1,12 +1,12 @@
#include <stdio.h> #include <stdio.h>
#include "arbre_de_codage/arbre_binaire.c" #include "arbre_de_codage/arbre_binaire.c"
#include "arbre_de_codage/liste.c" #define ASCII_EXT 256
Freq freq_apparition(FILE *file);
arbre huffman(arbre H, Freq L);
void quicksort(Freq L, Freq deb, Freq fin);
Freq partition (Freq L, Freq deb, Freq fin);
arbre huffman(arbre H, int Tp[], int Tl[]);
void frequence(int Tp[], int Tl[], FILE *file);
void tri_tab(int T[],int T2[],int n);
void afficher_tab(int Tp[], int Tl[], int n);
void init_tab(int T[], int Elt, int n);
// main_compress.c [nom_du_fichier_a_compresser] // main_compress.c [nom_du_fichier_a_compresser]
int main(int argc, char **argv){ int main(int argc, char **argv){
@ -24,167 +24,113 @@ int main(int argc, char **argv){
printf("\nErreur : Fichier %s inexistant\n",filename); printf("\nErreur : Fichier %s inexistant\n",filename);
return -2; return -2;
} }
// Récupérer fréquence
// Récupération des fréquences d'apparition des caractères dans le fichier int Tp[ASCII_EXT],Tl[ASCII_EXT];
Freq tmp,freq; init_tab(Tp,-1,ASCII_EXT);
freq = freq_apparition(file); init_tab(Tl,-1,ASCII_EXT);
tmp=freq; int compteur;
// Affichage pour vérification compteur=0;
while(!est_liste_vide(tmp)){ frequence(Tp,Tl,file);
printf("%d (%d)\n",tete_lettre(tmp),tete_freq(tmp)); // Tri
tmp=queue(tmp); tri_tab(Tp,Tl,ASCII_EXT);
} afficher_tab(Tp,Tl,ASCII_EXT);
// freq à ordonner dans l'ordre croissant
printf("Test Huffman\n");
arbre huff; arbre huff;
huff = huffman(creer_arbre_vide(),freq); huff = huffman(creer_arbre_vide(),Tp,Tl);
printf("FIN Test Huffman\n");
return 0; return 0;
} }
Freq freq_apparition(FILE *file){ void init_tab(int T[], int Elt, int n){
Freq text; int i;
text = creer_liste_vide(); for(i=0;i<n;i++){
int c; T[i]=Elt;
while((c=fgetc(file))!=EOF){
if(liste_rechercher(c,text)==1){
text=incrementer(c,text);
}
else{
text=ajouter(1,c,text);
}
} }
return text;
} }
arbre huffman(arbre H, Freq L){ void frequence(int Tp[], int Tl[], FILE *file){
int c;
while((c=fgetc(file))!=EOF){
if(Tl[c]!=-1){
Tp[c]++;
}
else{
Tl[c]=c;
Tp[c]=1;
}
}
}
void tri_tab(int T[],int T2[],int n){
int i,j,tmp,tmp2;
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){
if(T[i]>T[j]){
tmp=T[i];
tmp2=T2[i];
T[i]=T[j];
T2[i]=T2[j];
T[j]=tmp;
T2[j]=tmp2;
}
}
}
}
void afficher_tab(int Tp[], int Tl[], int n){
printf("\n");
int i;
for (i=0;i<n;i++){
printf("T[%d] = %d (%d)\n",i,Tp[i],Tl[i]);
}
}
int compteur_tab(int T[],int n){
int compteur,i;
compteur=0;
for(i=0;i<n;i++){
if(T[i]!=-1){
compteur++;
}
}
return compteur;
}
int i_index_min_tab(int T[],int i,int n){
int index_min;
index_min=0;
int k;
for(k=1;k<n;k++){
if(T[k]<T[index_min]){
index_min=k;
i--;
}
if(i==0){
return index_min;
}
}
return index_min;
}
arbre huffman(arbre H, int Tp[], int Tl[]){
/* /*
Création de l'arbre de codage de Huffman en considérant une liste avec les fréquences d'apparition des caractères ordonnée croissante Création de l'arbre de codage de Huffman en considérant une liste avec les fréquences d'apparition des caractères ordonnée croissante
*/ */
// récupérer les deux plus petits poids (cf : deux premieres occurences) // récupérer les deux plus petits poids (cf : deux premieres occurences)
Freq l; int i,compteur;
l=L;
printf("Test \n");
while(!est_liste_vide(l)){
printf("%d (%d)\n",tete_lettre(l),tete_freq(l));
l=queue(l);
}
int i;
i=0; i=0;
while((L->suiv->suiv != NULL)||i<50){ compteur=compteur_tab(Tl,ASCII_EXT);
printf("Test n°%d \n",i++); while(compteur != 1){
l=L; printf("\n Test n°%d \n",i++);
afficher(l); int l1,l2,p1,p2;
int al,bl,ap,bp; l1=Tl[i_index_min_tab(Tl,1,ASCII_EXT)];
al = tete_lettre(L); p1=Tp[i_index_min_tab(Tl,1,ASCII_EXT)];
ap = tete_freq(L); l2=Tl[i_index_min_tab(Tl,2,ASCII_EXT)];
L = queue(L); p2=Tp[i_index_min_tab(Tl,2,ASCII_EXT)];
bl = tete_lettre(L);
bp = tete_freq(L);
L = queue(L);
arbre fg,fd; arbre fg,fd;
fg=creer_feuille(al,ap); fg=creer_feuille(l1,p1);
fd=creer_feuille(bl,bp); fd=creer_feuille(l2,p2);
H=creer_arbre_huffman(0,ap+bp,fg,fd); H=creer_arbre_huffman(0,p1+p2,fg,fd);
printf("Test insérer\n"); // ajouter le nouveau poid
l=L; compteur--;
afficher(l);
L=inserer(ajouter(0,ap+bp,creer_liste_vide()),L);
l=L;
afficher(l);
printf("Affichage vérification\n");
} }
return H; return H;
} }
Freq partition (Freq L, Freq deb, Freq fin)
{
int permu;
int pivot;
Freq compt = deb;
Freq tmp;
if (!est_liste_vide(deb))
{
pivot = deb -> nb;
compt = deb;
tmp = deb -> suiv;
while(tmp != (fin -> suiv))
{
if(tmp -> nb)
{
permu = tmp->nb;
tmp = tmp -> suiv;
compt -> nb = permu;
}
tmp = tmp -> suiv;
}
permu = deb -> nb;
deb -> nb = compt -> nb;
compt -> nb=permu;
}
return compt;
}
void quicksort(Freq L, Freq deb, Freq fin)
{
if ((deb -> nb) < (fin -> nb))
{
Freq pivot = partition(L,deb,fin);
if(!est_liste_vide(pivot))
{
//quicksort(L,deb,precedent(L,pivot->nb));
}
}
}
/*
Freq fusion(Freq L, int i, int m, int j)
{
int tmp,u,k,v;
tmp=j-i+1;
k=0;
u=-i;
v=m;
while ((u<m) && (v<j))
{
if (L[u] < L[v])
{
tmp[k]=L[u]
u=u+1;
k=k+1;
}
else
{
tmp[k]=L[v];
v=v+1;
k=k+1;
}
}
if (u<m)
{
for(l=m;l<u;l++)
{
off = m-u;
L[j-off]=L[l];
}
}
for(l=0;l<k;l++)
{
L[l]=tmp[k];
}
}
Freq tri_fusion(L ,i,j)
{
if (i<j-1)
{
m=int((i+j)/2);
tri_fusion(i,m-1);
tri_fusion(m,j);
fusion(T,i,m,j);
}
}*/