﻿//---------------------------------------------------Début du fichier projet-------------------------------------------

/*Programme réalisée par FLEJEO Anna et HATIER Laurent.
Projet Toussaint 2008 : Analyse Textuelle.
Langage de programmation : C.
Explication du projet : Voir le fichier PDF ou les commentaires ci-après.
Date de derniére modification : 26/10/08
*/


//---------------------------------------------------Include pour le projet--------------------------------------------

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define TAILLEMAX 10000

//------------------------------------------------Structures et fonctions----------------------------------------------

/* Structure charUTF8 : permet de recuperer la valeur du charUTF8 et son code. */

typedef struct {
    int code;
    char* str;
} charUTF8;


/* Structure SCelluleCar : structure composée d'un compteur et d'un caractere de type charUTF8. */

struct SCelluleCar{
    int compteur;
    charUTF8* carac;
    struct SCelluleCar *pnext;
};
typedef struct SCelluleCar SCelluleCar;


/* Structure SCelluleMot : structure composée d'un compteur et d'un char[]
pour recupérer l'ensemble des charUTF8. */

struct SCelluleMot{
    int compteur2;
    char mot[TAILLEMAX];
    struct SCelluleMot *pnext2;
};
typedef struct SCelluleMot SCelluleMot;


/* Prototypages de toutes les fonctions utilisées dans le programme. */

int estPonctuation(charUTF8* chtest);
int getMaxCarac(SCelluleCar * pdebut);
int getMaxMots(SCelluleMot * pdebut2);
int getNbCaracteres(int compteur);
int getNbMots(int compteur);
void afficherListeChainee_Carac(SCelluleCar *pdebut);
void afficherListeChainee_Mots(SCelluleMot *pdebut2);
void aide();
void trierCaracteres(SCelluleCar *pdebut, int max,int compteurCaracteres);
void trierMots(SCelluleMot *pdebut2, int MAXI,int compteurMots);
void listeCarac(char** argv,FILE* file,char chaine[TAILLEMAX]);
void listeMot(char**argv,FILE* file,char chaine[TAILLEMAX]);
void PourcentageVoyCon(SCelluleCar *pdebut,int compteurCaracteres);
charUTF8* mallocCharUTF8 (char *str, int* curseur);

//--------------------------------------------------Debut du MAIN------------------------------------------------------

int main(int argc, char *argv[]){

    /*
    Initialisation des variables :
    - On initialise un pointeur de type FILE nous permettant par la suite de recupérer le texte en argv[2] et le lire "r".
    - On initialise une chaine[TAILLEMAX] pour pouvoir recupérer la ligne à étudier.
    */

    FILE* test = NULL;
    test = fopen(argv[2],"r");
    char chaine[TAILLEMAX];

//---------------------------------------------------Cas d'erreur------------------------------------------------------

    if((test == NULL)||(argc<2)){
        printf("ERREUR, vous n'avez pas entrer le bon fichier et/ou oublier l'option. \n");
        aide();
        return 0;
    }

//-------------------------------------------------Les Options---------------------------------------------------------

    if(argv[1][0]=='-'){ /* Si l'utilisateur rentre en premier caractére - alors : */
        if(argv[1][1]=='h'){
            aide();
        }else if((argv[1][1]=='c')||(argv[1][1]=='C')||(argv[1][1]=='v')||(argv[1][1]=='k')){
            listeCarac(argv,test,chaine);
        }else if((argv[1][1]=='w')||(argv[1][1]=='W')||(argv[1][1]=='d')||(argv[1][1]=='p')||(argv[1][1]=='m')){
            listeMot(argv,test,chaine);
        }else{
            printf("ERREUR, vous n'avez pas saisi une option existante. \n");
            aide();
        }
    fclose(test);

    }else{ /* Sinon on affiche le message d'erreur suivant : */
        printf("Vous avez oublié de mettre le tiret '-' correspondant aux options disponibles.");
        }

return 0;
}

//----------------------------------------------------Fin du MAIN----------------------------------------------------------



//-------------------------------------------Fonctions Utilisées dans le MAIN :--------------------------------------------


//-------------------------Fonction afficherListeChainee_Carac : Afficher la liste chainée des Caracteres------------------

/*
La fonction afficherListeChainee_Carac(SCelluleCar * pdebut) affiche la liste chainée des caractères
obtenue dans listeCarac(char**argv,FILE* file,char chaine[TAILLEMAX]). Pour cela, on a besoin du paramètre
qui est SCelluleMot *pdebut qui doit être différent de NULL pour que la fonction afficher fonctionne.
Nous bouclons tant que pcourant est différent de NULL (bien évidemment, nous avons initialiser
SCelluleMot *pcourant = pdebut) et on affiche chaque cellule de liste chainée.
On a utilisé "fprintf" pour pouvoir afficher le résultat dans un fichier de sortie, ici sortie-listechainee-carac.txt.
*/

void afficherListeChainee_Carac(SCelluleCar *pdebut){
    SCelluleCar *pcourant=pdebut;
    FILE* sortie = NULL;
    int boolean42=0;
    sortie = fopen("sortie-listechainee-carac.txt","w");
    if(sortie != NULL){
        fprintf(sortie,"Voici la liste chainée des caractères du texte choisi :\n \n");
        while(boolean42 != 1){
            if(pcourant!=NULL){
                fprintf(sortie," |%s|%d|-> ",pcourant->carac->str,pcourant->compteur);
                pcourant=pcourant->pnext;
            }else{
                fprintf(sortie,"NULL");
                boolean42=1;
            }
        }
        printf("\nFichier sortie-listechainee-carac créé \n");
        fclose(sortie);
    }
}

//----------------------------Fonction afficherListeChainee_Mots : Afficher la liste chainée des Mots----------------------

/*
La fonction afficherListeChainee_Mots(SCelluleMot * pdebut2) affiche la liste chainée des mots obtenue dans
listeMot(char**argv,FILE* file,char chaine[TAILLEMAX]). Pour cela, on a besoin du paramètre qui est
SCelluleMot *pdebut2 qui doit être différent de NULL pour que la fonction afficherListeChainee_Mots fonctionne.
Nous bouclons tant que pcourant2 est différent de NULL (bien évidemment, nous avons initialiser
SCelluleMot *pcourant2 = pdebut2) et on affiche chaque cellule de liste chainée.
On a utilisé "fprintf" pour pouvoir afficher le résultat dans un fichier de sortie, ici "sortie-listechainee-mot.txt".
*/

void afficherListeChainee_Mots(SCelluleMot *pdebut2){
    SCelluleMot *pcourant2=pdebut2;
    FILE* sortie2 = NULL;
    int boolean42=0;
    sortie2 = fopen("sortie-listechainee-mot.txt","w");
    if(sortie2 != NULL){
        fprintf(sortie2,"Voici la liste chainée des mots du texte choisi :\n \n");
        while(boolean42!=1){
            if(pcourant2!=NULL){
                fprintf(sortie2,"|%s|%d|-> ",pcourant2->mot,pcourant2->compteur2);
                pcourant2=pcourant2->pnext2;
            }else{
                fprintf(sortie2,"NULL");
                boolean42=1;
            }
        }
    printf("\nFichier sortie-listechainee-mot créé \n");
    fclose(sortie2);
    }
}

//----------------------------------Fonction getMaxCarac : Retourner la plus grande occurance------------------------------------

/*
La fonction getMaxCarac(SCelluleCar * pdebut) retourne l'occurence de caractère la plus grande. On a en paramètre
le pointeur SCelluleCar *pdebut qui doit être différent de NULL pour que la fonction fonctionne correctement.
Par la suite, on a defini SCelluleCar * pcourant= pdebut pour pouvoir parcourir toute la liste chainée et donc
en déduire le MAXI.
*/

int getMaxCarac(SCelluleCar * pdebut){
    SCelluleCar *pcourant=pdebut;
    int MAXI=0;
        do{
            if(pcourant->compteur > MAXI){
                MAXI = pcourant->compteur;
                pcourant=pcourant->pnext;
            }else{
            pcourant=pcourant->pnext;
            }

        }while(pcourant != NULL);
    return MAXI;
}

//----------------------------------Fonction getMaxMots : Retourner la plus grande occurance-----------------------------------

/*
La fonction getMaxMots(SCelluleMot * pdebut2) retourne l'occurence de caractère la plus grande. On a en paramètre
le pointeur SCelluleMot *pdebut2 qui doit être différent de NULL pour que la fonction fonctionne correctement.
Par la suite, on a defini SCelluleMot * pcourant2= pdebut2 pour pouvoir parcourir toute la liste chainée, et donc
en déduire le MAXI.
*/

int getMaxMots(SCelluleMot * pdebut2){
    SCelluleMot *pcourant2=pdebut2;
    int MAXI=0;
        do{
            if(pcourant2->compteur2 > MAXI){
                MAXI = pcourant2->compteur2;
                pcourant2=pcourant2->pnext2;
            }else{
            pcourant2=pcourant2->pnext2;
            }
        }while(pcourant2 != NULL);
    return MAXI;
}

//--------------------------------Fonction getNbCaracteres : Retouner le compteurCaractères---------------------------------

/*
La fonction getNbCaracteres(int compteur) retourne le nombre de caractères dans un texte. Elle prend en
paramètre un compteur qui doit être différent de 0 car la fonction trierCaracteres ne pourra pas établir le
poucentage des caractéres.
*/

int getNbCaracteres(int compteur){
    return compteur;
}

//---------------------------------------Fonction getNbMots : Retouner le compteurMots--------------------------------------

/*
La fonction getNbCaracteres(int compteur) retourne le nombre de mots dans un texte. Elle prend en
paramètre un compteur qui doit être différent de 0 car la fonction trierMots ne pourra pas établir le
poucentage des mots.
*/

int getNbMots(int compteur){
    return compteur;
}

//-----------------------------------Fonction trierCaracteres : Afficher le % des caractères--------------------------------

/*
La fonction trierCaracteres(SCelluleCar * pdebut, int MAXI,int compteurCaracteres) affiche le tri et donc le tableau
des pourcentages des caractères dans l'ordre décroissant.Grâce au "fprintf" utilisé dans cette fonction, le
tableau se trouvera dans un fichier texte nommé : "sortie-tableau-cara.txt".

Pour le bon fonctionnement de la méthode, on a 3 paramètres :

- SCelluleCar * pdebut : nous avons donc besoin du 1er pointeur pdebut pour pouvoir trier l'ensemble de la liste :
Nous créons alors SCelluleCar * pcourant=pdebut pour parcourir toute la chaine et donc afficher le tri.

- int MAXI : cette variable n'est rien dautre que le resultat de la fonction getMaxCarac qui nous sera fort utile
pour afficher le tri des caractères.

- int compteurCaracteres : cette variable n'est rien d'autres que le résultat de la fonction getNbCaracteres qui nous
sera fort utile pour le calcul du pourcentage des caractères dans le texte choisi.

Explication de la méthode utilisée pour afficher le tri :
Nous avons donc recupérer la plus grande occurence dans l'ensemble de la liste chainée grâce à la méthode getMaxCarac.
Nous utilisons alors une boucle for en decrémentant le MAXI : on parcourt alors la chaine en cherchant une occurence
égale au MAXI : si on trouve, on affiche le caractère et son occurence sinon on continue à lire la liste chainée tant
que le pointeur est différent de NULL. Quand on arrive à la fin de la liste chaînée, on decrémente le MAXI et on
recommence jusqu'à MAXI>0.
*/

void trierCaracteres(SCelluleCar *pdebut, int MAXI,int compteurCaracteres){
    SCelluleCar *pcourant=pdebut;
    FILE* sortie3 = NULL;
    sortie3 = fopen("sortie-tableau-cara.txt","w");
    int max;
    if(sortie3 != NULL){
        fprintf(sortie3,"Voici le tableau des pourcentages des caractères du texte choisi :\n \n");
        fprintf(sortie3,"  Occurence |   Pourcentage   | Caractères");
        fprintf(sortie3,"\n--------------------------------------------\n");
        for(max=MAXI;max>0;max--){
            pcourant=pdebut;
            do{
                if((pcourant->compteur)==max){
                    if(pcourant->carac->code ==32){
                        fprintf(sortie3,"\n   %d    |   %f %%   |   espace \n",pcourant->compteur,(float)((pcourant->compteur)*100)/(float)compteurCaracteres);
                        fprintf(sortie3,"--------------------------------------------\n");
                    }else{
                        fprintf(sortie3,"\n   %d    |   %f %%   |   %s \n",pcourant->compteur,(float)((pcourant->compteur)*100)/(float)compteurCaracteres, pcourant->carac->str);
                        fprintf(sortie3,"--------------------------------------------\n");
                    }
                    pcourant=pcourant->pnext;
                }else{
                    pcourant=pcourant->pnext;
                }

            }while(pcourant != NULL);
        }
        printf("\nFichier sortie-tableau-cara.txt créé \n");
        fclose(sortie3);
    }
}

//------------------------Fonction PourcentageVoyCon : Afficher le % des Voyelles et Consomnes------------------------------

/*
La fonction PourcentageVoyCon(SCelluleCar *pdebut,int compteurCaracteres) retourne le pourcentage des voyelles et
des consonnes dans un texte choisi. Nous avons fait la différence entre les voyelles majuscules et les voyelles
minuscules et de même pour les consonnes.Pour cela, nous comparons le code du caractère etudié :
 - Si ce dernier appartient au voyelles minuscules alors on verifie :
     - Si l'égalité est vrai alors on augmente le pourcentage des voyelles minuscules 
     - sinon on incrémente celui des consonnes.
 - Sinon ce dernier appartient au voyelles majuscules et on verifie :
     - Si l'égalité est vrai alors on augmente le pourcentage des voyelles majuscules 
     - Sinon on incrémente celui des consonnes.
*/
void PourcentageVoyCon(SCelluleCar *pdebut, int compteurCaracteres){
    SCelluleCar *pcourant=pdebut;
    FILE* sortie9 = NULL;
    sortie9 = fopen("sortie-tableau-voyelles-consonnes.txt","w");
    int max;
    float percentV=0;
    float percentV2=0;
    float percentC=0;
    float percentC2=0;
    if(sortie9 != NULL){
        fprintf(sortie9,"Voici le tableau des pourcentages des voyelles et des consonnes du texte choisi :\n \n");
        fprintf(sortie9,"            |     Minuscules     |    Majuscules   ");
        fprintf(sortie9,"\n---------------------------------------------------\n");
        pcourant=pdebut;
        do{
            if((pcourant->carac->code>96)&&(pcourant->carac->code<123)){
                if((pcourant->carac->code==97)||(pcourant->carac->code==101)||(pcourant->carac->code==105)||(pcourant->carac->code==111)||(pcourant->carac->code==117)||(pcourant->carac->code==121)){
                    percentV = percentV + (float)((pcourant->compteur)*100)/(float)compteurCaracteres;
                    pcourant=pcourant->pnext;
                }else{
                    percentC = percentC + (float)((pcourant->compteur)*100)/(float)compteurCaracteres;
                    pcourant=pcourant->pnext;
                    }
            }else if((pcourant->carac->code>64)&&(pcourant->carac->code<91)){
                if((pcourant->carac->code==65)||(pcourant->carac->code==69)||(pcourant->carac->code==73)||(pcourant->carac->code==79)||(pcourant->carac->code==85)||(pcourant->carac->code==89)){
                    percentV2 = percentV2 + (float)((pcourant->compteur)*100)/(float)compteurCaracteres;
                    pcourant=pcourant->pnext;
                }else{
                    percentC2 = percentC2 + (float)((pcourant->compteur)*100)/(float)compteurCaracteres;
                    pcourant=pcourant->pnext;
                    }
            }else{
                pcourant=pcourant->pnext;
                }
            }while(pcourant != NULL);
        fprintf(sortie9,"Voyelles    |     %f %%    |     %f %%    \n",percentV,percentV2);
        fprintf(sortie9,"---------------------------------------------------\n");
        fprintf(sortie9,"Consonmes   |     %f %%    |     %f %%    \n",percentC,percentC2);

        printf("\nFichier sortie-tableau-voyelles-consonnes.txt créé \n");
        fclose(sortie9);
    }
}
//------------------------------------Fonction trierMots : Afficher le % des mots--------------------------------------------

/*
La fonction trierMots(SCelluleMot *pdebut2, int MAXI,int compteurMots) affiche le tri et donc le tableau
des pourcentages des motss dans l'ordre décroissant.Grâce au "fprintf" utilisé dans cette fonction, le
tableau se trouvera dans un fichier texte nommé : "sortie-tableau-mot.txt".

Pour le bon fonctionnement de la méthode, on a 3 paramètres :

- SCelluleMot * pdebut2 : nous avons donc besoin du 1er pointeur pdebut2 pour pouvoir trier l'ensemble de la liste :
Nous créons alors SCelluleMot * pcourant2=pdebut2 pour parcourir toute la chaine et donc afficher le tri.

- int MAXI : cette variable n'est rien dautre que le resultat de la fonction getMaxCarac qui nous sera fort utile
pour afficher le tri des caractères.

- int compteurMots : cette variable n'est rien d'autres que le résultat de la fonction getNbCaracteres qui nous
sera fort utile pour le calcul du pourcentage des caractères dans le texte choisi.

Explication de la méthode utilisée pour afficher le tri :
Nous avons donc recupérer la plus grande occurence dans l'ensemble de la liste chainée grâce à la méthode getMaxMots.
Nous utilisons alors une boucle for en decrémentant le MAXI : on parcourt alors la chaine en cherchant une occurence
égale au MAXI : si on trouve, on affiche le mot et son occurence sinon on continue à lire la liste chainée tant
que le pointeur est différent de NULL. Quand on arrive à la fin de la liste chaînée, on decrémente le MAXI et on
recommence jusqu'à MAXI>0.
*/

void trierMots(SCelluleMot *pdebut2, int MAXI,int compteurMots){
    SCelluleMot *pcourant2=pdebut2;
    int max2;
    FILE* sortie4 = NULL;
    sortie4 = fopen("sortie-tableau-mot.txt","w");
    if(sortie4 != NULL){
        fprintf(sortie4,"Voici le tableau des pourcentages des mots du texte choisi :\n \n");
        fprintf(sortie4,"   Occurences   |    Pourcentage     |     Mots     ");
        fprintf(sortie4,"\n------------------------------------------------------\n");
        for(max2=MAXI;max2>0;max2--){
            pcourant2=pdebut2;
            do{
                if((pcourant2->compteur2)==max2){
                     fprintf(sortie4,"\n      %d      |     %f %%     |     %s \n",pcourant2->compteur2,(float)((pcourant2->compteur2)*100)/(float)compteurMots,pcourant2->mot);
                     fprintf(sortie4,"------------------------------------------------------\n");
                    pcourant2=pcourant2->pnext2;
                }else{
                pcourant2=pcourant2->pnext2;
                }
            }while(pcourant2 != NULL);
        }
        printf("\nFichier sortie-tableau-mot.txt créé \n");
        fclose(sortie4);
    }
}

//-------------------------------Fonction listeCarac : Créer la liste des caractères---------------------------------------

/*
La fonction listeCarac(char**argv,FILE* file,char chaine[TAILLEMAX]) crée la liste chainée des caractéres avec
leur occurence.

Pour le bon fonctionnement de la méthode, on a 3 paramètres :

- char**argv : nous avons donc besoin d'un argument que l'on recupère dans la ligne de commande de l'utilisateur.
Cet argument est tout simplement le nom du texte à étudier aui, dans notre programme, est recupéré en 3e position,
après le nom de l'éxécutable et l'option choisie. Sans ce dernier, le programme ne pourra pas fonctionner.

- FILE *file : ce paramètre est très important puisque si aucun texte.txt n'est rentré au tout début du programme,
nous pourrons pas étudier ce texte, et par conséquent nous pourrons pas créer la liste chainée des caractères.

- char chaine[TAILLEMAX] : ce paramètre nous est utile pour les mêmes raisons que ci-dessus : si ce paramètre est
NULL alors la fonction "fgets" ne pourra pas fonctionner.

Explication de la méthode utilisée pour afficher la liste chainée des caractères :
Pour créer la liste chainée, nous allons donc tout simplement lire les caractères les uns après les autres. Le premier
caractère sera stocké dans un SCelluleCar *pdebut, ou encore : pdebut->carac=ch, avec un compteur initialisé à 1 et
le pointeur suivant qui n'est rien d'autre que pnext pointera sur NULL. Ce "pdebut" sera fixe grâce à l'utlisation
d'une variable appelée boolean2. Nous allons donc maintenant initialisé  SCelluleCar *pcourant = pdebut.
Pour les autres caractères, nous allons donc comparer le caractère du "pcourant" avec celui étudié :

- Si les 2 sont identiques, alors on incrémente le compteur et on passe au prochain caractère
- Sinon si le pointeur courant ne possède pas un pointeur suivant "NULL", alors on deplace le pointeur courant à la
prochaine cellule à étudier.
- Sinon, on crée une nouvelle cellule avec le caractère a étudié, le compteur initialisé à 1 et son suivant est "NULL".

Par la suite, nous gérons l'option avec un switch :
l'option choisie est "-C", alors on utilise les fonctions getNbCaracteres(compteurCaracteres),
trierCaracteres(pdebut,getMaxCarac(pdebut),getNbCaracteres(compteurCaracteres)) et on affichera le tableau des
pourcentages.
l'option choisie est "-c", alors on affiche le nombre de caractères.
l'option choisie est "-v", on utilise la fonction afficherListeChainee_Carac(SCelluleCar *pdebut);
pour afficher la liste chainée.
*/

void listeCarac(char**argv,FILE* file,char chaine[TAILLEMAX]){
    int c,boolean;
    FILE* test=file;
    SCelluleCar *pcourant;
    SCelluleCar *pdebut;
    int compteurCaracteres=0;
    int boolean2=0;

    printf("Patientez s'il vous plait...");

    while(fgets(chaine,TAILLEMAX,test)!= NULL){
        c=0;
        while(chaine[c]!=0){
            charUTF8 *ch = mallocCharUTF8(chaine,&c);
            compteurCaracteres++;
            if(boolean2==0){
                pdebut = (SCelluleCar*)malloc(sizeof(SCelluleCar));
                pdebut->carac=ch;
                pdebut->compteur = 1;
                pdebut->pnext = NULL;
                pcourant=pdebut;
                boolean2=1;
                free(ch->str);
                free(ch);
            }else{
                pcourant = pdebut;
                boolean = 0;
                do{
                    if(strcmp((pcourant->carac->str),ch->str)==0){
                        pcourant->compteur++;
                        boolean = 1;
                    }else if(pcourant->pnext != NULL){
                        pcourant=pcourant->pnext;
                        }else{
                            pcourant->pnext = (SCelluleCar*)malloc(sizeof(SCelluleCar));
                            pcourant->pnext->carac=ch;
                            pcourant->pnext->compteur = 1;
                            pcourant->pnext->pnext = NULL;
                            pcourant=pcourant->pnext;
                            boolean = 1;
                            }
                    }while(boolean != 1);
                }
        }
    }

    switch(argv[1][1]){

        case 'C' :
        getNbCaracteres(compteurCaracteres);
        trierCaracteres(pdebut,getMaxCarac(pdebut),getNbCaracteres(compteurCaracteres));
        break;

        case 'c' :
        printf("\nIl y a %d caractères dans ce texte\n",compteurCaracteres);
        break;

        case 'k' :
        getNbCaracteres(compteurCaracteres);
        PourcentageVoyCon(pdebut,getNbCaracteres(compteurCaracteres));
        break;

        case 'v' :
        afficherListeChainee_Carac(pdebut);
        break;

    }
}

//------------------------------------Fonction listeMot : Créer la liste des mots------------------------------------------

/*
La fonction listeMots(char**argv,FILE* file,char chaine[TAILLEMAX]) crée la liste chainée des mots avec
leur occurence.

Pour le bon fonctionnement de la méthode, on a 3 paramètres :

- char**argv : nous avons donc besoin d'un argument que l'on recupère dans la ligne de commande de l'utilisateur.
Cet argument est tout simplement le nom du texte à étudier aui, dans notre programme, est recupéré en 3e position,
après le nom de l'éxécutable et l'option choisie. Sans ce dernier, le programme ne pourra pas fonctionner.

- FILE *file : ce paramètre est très important puisque si aucun texte.txt n'est rentré au tout début du programme,
nous pourrons pas étudier ce texte, et par conséquent nous pourrons pas créer la liste chainée des caractères.

- char chaine[TAILLEMAX] : ce paramètre nous est utile pour les mêmes raisons que ci-dessus : si ce paramètre est
NULL alors la fonction "fgets" ne pourra pas fonctionner.

Explication de la méthode utilisée pour afficher la liste chainée des mots :
Pour créer la liste chainée, nous allons donc tout simplement concatener les caractères UTF8 les uns après les autre,
tant que le caractère étudié ne soit pas un espace ou un retour à la ligne. Le premier mot sera stocké dans un
SCelluleMot *pdebut2, et l'on definira le "pdebut2->mot" ainsi : strcpy(mot, motUTF8). On initialise un compteur à 1
et le pointeur suivant, qui n'est rien d'autre que pnext2, pointera sur NULL. Ce "pdebut2" sera fixe grâce à
l'utlisation d'une variable appelée boolean3. Nous allons donc maintenant initialisé  SCelluleCar *pcourant = pdebut.
Pour les autres mots, nous allons donc comparer le mot du "pcourant2" avec celui a étudié :

- Si les 2 sont identiques, alors on incrémente le compteur, on met la variable motUTF8 à 0 et
on passe au prochain mot.
- Sinon si le pointeur courant ne possède pas un pnext2 "NULL", alors on deplace le pointeur courant (pcourant2)à la
prochaine cellule à étudier.
- Sinon, on crée une nouvelle cellule avec le mot étudié, le compteur initialisé à 1 et son suivant initialisé à
"NULL".

Il faudra également gérer un cas pour le dernier mot du texte. Pour celà, il faut se référencer à l'explication
ci-après, dans le code même.

Par la suite, nous gérons l'option avec un switch:
l'option choisie est "-W", alors on utilise les fonctions getNbMots(compteurMots),
trierMots(SCelluleMot *pdebut2, int MAXI,int compteurMots) et on affichera le tableau des
pourcentages.
l'option choisie est "-d", alors on affiche le nombre de mots différents.
l'option choisie est "-m", alors on affiche le nombre moyen de caractéres par mots : Nous avons décidé d'afficher un
int au lieu d'un float car un nombre entier est plus sensé qu'un nombre à virgule.
l'option choisie est "-p", on utilise la fonction afficherListeChainee_Mots(SCelluleMot *pdebut2);
pour afficher la liste chainée.
*/

void listeMot(char**argv,FILE* file,char chaine[TAILLEMAX]){
    int c,boolean;
    FILE* test=file;
    char motUTF8[10000];
    int compteurMots=1;
    int compteurCaracteres=0;
    SCelluleMot *pcourant2;
    SCelluleMot *pdebut2;
    int compteurMotsDif=1;
    int boolean3=0;

    printf("Patientez s'il vous plait...");

    while(fgets(chaine,TAILLEMAX,test)!= NULL){
        c=0;
        while(chaine[c]!=0){
            charUTF8 *ch = mallocCharUTF8(chaine,&c);
            compteurCaracteres++;
            if(!estPonctuation(ch)){
                compteurMots++;
            }
            if((((ch->code>31)&&(ch->code<39))||(ch->code==46)||(ch->code==44)||((ch->code>39)&&(ch->code<45))||((ch->code>57)&&(ch->code<65)))){
                ch->str = 0;
            }else{
                strcat(motUTF8,ch->str);
                }
            if(((ch->code)==32)||((ch->code)==10)){
                if(boolean3==0){
                    pdebut2 = (SCelluleMot*)malloc(sizeof(SCelluleMot));
                    strcpy(pdebut2->mot,motUTF8);
                    pdebut2->compteur2 = 1;
                    pdebut2->pnext2 = NULL;
                    boolean3=1;
                    pcourant2=pdebut2;
                    motUTF8[0]='\0';
                }else{
                    boolean = 0;
                    pcourant2=pdebut2;

                    do{
                        if(strcmp(pcourant2->mot,motUTF8)==0){
                            pcourant2->compteur2++;
                            boolean = 1;
                        }else if(pcourant2->pnext2 != NULL){
                            pcourant2=pcourant2->pnext2;
                            }else{
                                pcourant2->pnext2 = (SCelluleMot*)malloc(sizeof(SCelluleMot));
                                strcpy(pcourant2->pnext2->mot,motUTF8);
                                pcourant2->pnext2->compteur2 = 1;
                                pcourant2->pnext2->pnext2 = NULL;
                                pcourant2=pcourant2->pnext2;
                                compteurMotsDif++;
                                boolean = 1;
                                }
                        }while(boolean != 1);
                    motUTF8[0]='\0';
                    }
            }
        }
    }

    switch(argv[1][1]){

        case 'W' :
        getNbMots(compteurMots);
        trierMots(pdebut2,getMaxMots(pdebut2),getNbMots(compteurMots));
        break;

        case 'd' :
        printf("\nIl y a %d mots différents dans ce texte\n",compteurMotsDif);
        break;

        case 'w' :
        printf("\nLe nombre de mots est : %d\n",compteurMots);
        break;

        case 'm' :
        printf("\nLe moyenne de caractères par mots : %d\n",compteurCaracteres/compteurMots);
        break;

        case 'p' :
        afficherListeChainee_Mots(pdebut2);
        break;

    }
}

//--------------------------Fonction estPonctuation : Verifier si le caractère est une ponctuation--------------------------

/*
La fonction estPonctuation(charUTF8* chtest) retourne un int qui est considéré comme un boolean. Elle retourne faux
si le caractéres de type charUTF8 vérifie une des conditions du "if", sinon elle retourne vrai.
*/

int estPonctuation(charUTF8* chtest){
	if(((chtest->code>31)&&(chtest->code<39))||(chtest->code==32)||((chtest->code>39)&&(chtest->code<45))||((chtest->code>57)&&(chtest->code<65))){
		return 0;
	}
	return 1;
}

//-------------------------------------------Fonction aide : Afficher l'aide------------------------------------------------

/* La fonction aide() affiche l'aide en cas de demande. */

void aide(){
    printf("Exemple d'utilisation : monCompile -option montexte.txt\n");
    printf("Voici les option disponibles pour ce programme : \n");
    printf(" -c: compter le nombre de caractères,\n");
    printf(" -C: déterminer les caractères les plus fréquents, par ordre décroissant,\n");
    printf(" -w: compter le nombre total de mots,\n");
    printf(" -d: compter le nombre de mots différents,\n");
    printf(" -W: déterminer les mots les plus fréquents, par ordre décroissant,\n");
    printf(" -m: calculer la moyenne des caractères par mot,\n");
    printf(" -v: afficher la liste chainée comportant l'ensemble des lettres du texte,\n");
    printf(" -p: afficher la liste chainée comportant l'ensemble des mots différents,\n");
    printf(" -k: détermine le pourcentage des voyelles et des consonnes dans un texte.\n");
}

//----------------------------------Fonction mallocCharUTF8 : Allouer l'espace pour un charUT8-------------------------------

charUTF8* mallocCharUTF8 (char *str, int* curseur)
{
    charUTF8* cUTF8 = (charUTF8*)malloc(sizeof(charUTF8));
    cUTF8->str = (char*)malloc(5*sizeof(char));
    int n;
    char c = str[*curseur];
    if ((c&128) == 0)
    {
        cUTF8->str[0] = str[*curseur]&255;
        cUTF8->str[1] = 0;
        cUTF8->code = cUTF8->str[0];
        n=1;
    }
    else if (((c&128) == 128) && ((c&64) == 64) && ((c&32) == 0))
    {
        cUTF8->str[0] = str[*curseur]&255;
        cUTF8->str[1] = str[*curseur+1]&255;
        cUTF8->str[2] = 0;
        cUTF8->code = (cUTF8->str[0]&255)*256+(cUTF8->str[1]&255);
        n=2;
    }
    else if (((c&128) == 128) && ((c&64) == 64) && ((c&32) == 32) && ((c&16) == 0))
    {
        cUTF8->str[0] = str[*curseur]&255;
        cUTF8->str[1] = str[*curseur+1]&255;
        cUTF8->str[2] = str[*curseur+2]&255;
        cUTF8->str[3] = 0;
        cUTF8->code = (cUTF8->str[0]&255)*256*256+(cUTF8->str[1]&255)*256+(cUTF8->str[2]&255);
        n=3;
    }
    else if (((c&128) == 128) && ((c&64) == 64) && ((c&32) == 32) && ((c&16) == 16) && ((c&8) == 0))
    {
        cUTF8->str[0] = str[*curseur]&255;
        cUTF8->str[1] = str[*curseur+1]&255;
        cUTF8->str[2] = str[*curseur+2]&255;
        cUTF8->str[3] = str[*curseur+3]&255;
        cUTF8->str[4] = 0;
        cUTF8->code = (cUTF8->str[0]&255)*256*256*256+(cUTF8->str[1]&255)*256*256+(cUTF8->str[2]&255)*256+(cUTF8->str[3]&255);
        n=4;
    }
    else // Error
    {
        free(cUTF8->str);
        free(cUTF8);
        return NULL;
    }
    *curseur+=n;
    return cUTF8;
}

//---------------------------------------------------Fin du fichier projet--------------------------------------------------
