tree.c 7.35 KB
// --------------------------------------------------------
// Projet IMA3 2019 - Lecture d'une bibliothèque
// Décompte du nombre de fautes d'orthographe dans un texte
// Normand Quentin & Rouillé Guillaume
// --------------------------------------------------------

#include "tree.h"

// Fonction permettant de savoir si la structure est vide
bool is_empty_tree(Node Tree)
{
  return(Tree==NULL);
}

// Fonction permettant de savoir si le tableau 'next' est un tableau de pointeurs NULL
bool is_leaf(Node Tree)
{
  for(int i=0; i<NB_CARAC; i++)
    if(Tree->next[i] != NULL)
      return false;
  return true;
}

// Initialisation de la structure accueillant le dictionnaire
void init_tree(Node* Tree)
{
  if(is_empty_tree(*Tree))
    {
      *Tree = malloc(sizeof(node));
      (*Tree)->letter = '?'; // caractère choisi arbitrairement
      (* Tree)->endWord = false;
      for(int i=0; i<NB_CARAC; i++)
        (*Tree)->next[i] = NULL; // initialisation du tableau 'next' à un tableau de pointeurs NULL
    }
}

// Détermine l'indice de rangement dans le tableau 'next' du caractère 'letter'
int find_caract_indice(char letter) // Ne fonctionne pas pour les caractères accentués
{
  //printf("__%d__\n", letter);
  if(letter>=97 && letter<=122) return letter-'a';
  if(letter>=65 && letter<=90) return letter-'A';
  if(letter == 39) return letter-13; // l'apostrophe est placée en 27ème position
  //if(letter>=192) {printf("%d", letter-166); return letter-166;} //-192+26
}

// Fonction d'ajout d'un mot 'word' dans la structure 'tree' de type 'arbre indexé'
void add_in_tree(Node Tree, char word[])
{
  int j=0; // indice du caractère dans le mot 'word'
  int ind; // indice du caractère dans le tableau 'next'
  Node Tree2 = Tree;
  while(word[j] != '\0') // on parcourt tout le mot 'word'
    {
      /*if(is_leaf(Tree2)) // a retirer
        printf("empty\t");*/
      char letter = word[j];
      ind = find_caract_indice(letter);
      if(Tree2->next[ind]!=NULL) // si le pointeur du tableau 'next' corresdant au caractère lu n'est pas NULL, on s'insère dans cette 'branche' de l'arbre indexé et on continue avec le caractère suivant
      {
        Tree2 = Tree2->next[ind];
	/* printf("%c %d\t", letter, ind);
	   printf("okA %d\n", j);*/
      }
      else // sinon, on ajoute une nouvelle cellule de type 'struct node' et on y insère les informations concernant le caractères
      {
        Node new = NULL;
        new = malloc(sizeof(node));
        new->letter = letter; // le caractère
        for(int i=0; i<NB_CARAC; i++) // un tableau de pointeurs NULL
          {
            new->next[i]=NULL;
          }
        Tree2->next[ind] = new;  // on fait pointé le tableau du caractère précédent vers cette cellule (vers ce caractère)
        /*if(!(Tree2->endWord)) // si le caractère n'est pas un caractère de fin, on le met à 'false' -> UTILITE ?
          Tree2->endWord = false;*/
        Tree2=Tree2->next[ind]; // on se place au niveau du caractère suivant dans l'arbre indexé
        /*printf("%c %d\t", letter, ind);
	  printf("okB %d\n", j);*/
      }
      j++;
      if(word[j]=='\0') // si le caractère suivant est la fin de la chaîne, on dit que le caractère précédent est un caractère de fin
        Tree2->endWord = true;
    }
  //printf("ok\n");
}

// Fonction qui détermine si le caractère est un caractère de fin de mot (espace, ',', ';', '.', etc..)
bool is_end_caract(char letter)
{
  if(letter==0) return true;
  if((letter>=32 && letter<=38)||(letter>=40 && letter<=47)||(letter>=58 && letter<=64)||(letter>=123 && letter<=126)||(letter==128)) return true;
  return false;
}

// Renvoi l'indice maximum du mot 'word'
char max_index(char word[])
{
  int index = 0;
  while(!is_end_caract(word[index]))
    index++;
  return index;
}

void scan_word(Node Tree, char word[], int* error, FILE* fp_txt) // si un mot démarre juste après un caractère de fin, la fonction ne lit pas les mots séparément
{
  bool endWord = false;
  bool stop = false;
  int ind = 0;
  int indice;
  char letter;
  Node Tree2 = Tree;
  while(!is_end_caract(word[ind]))
  {
    stop = false;
    letter = word[ind];
    indice = find_caract_indice(letter);
    
    if(Tree2 != NULL && Tree2->next[indice]!=NULL)
    {
      ind++;
      Tree2 = Tree2->next[indice];
      endWord = Tree2->endWord;
    }
    else
    {
      add_error(error, word, ind, Tree, fp_txt);
      //printf("%d\n", ind);
      ind = max_index(word);
      //printf("%d\n", ind);
      stop = true;
      endWord = false;
    }
  }
  if(!endWord && !stop)
    {
      add_error(error, word, ind, Tree, fp_txt);
    }
}

void add_error(int* error, char word[], int index, Node Tree, FILE* fp_txt)
{
  (*error)++;
  if(index==0)
    {
      printf("Le mot %s ne correspond à aucun mot du dictionnaire.\n\n", word);
      return;
    }
  else if(index<strlen(word))
      printf("Il y a une erreur dans le mot '%s', au caractère %c d'incide %d.\n\n", word, word[index], index);
  else
      printf("Il manque au moins une lettre au mot '%s'.\n\n", word);
  make_correction(word, index, Tree, fp_txt);
}

void make_correction(char word[], int index, Node Tree, FILE* fp_txt)
{
  return;
}

void init_pgrm(void)
{
  printf("\n------------------------------------------\n");
  printf("Correcteur ortographique.\n");
  printf("Normand Quentin & Rouillé Guillaume.\n");
  printf("------------------------------------------\n\n");
}

bool no_accent(char word[])
{
  int index_max = max_index(word);
  for(int i=0; i<index_max; i++)
    if(word[i]<0) return false;
  return true;
}

void read_txt(FILE* fp, Node* Tree, int* error, FILE* fp_txt)
{
  char word[MAX];
  while(1)
  {
    if(fscanf(fp, "%s", word)!=1)
      break;
    if(no_accent(word)) // !!! MOTS AVEC ACCENTS NON PRIS EN COMPTE
      scan_word(*Tree, word, error, fp_txt);
  }
  if(feof(fp)) printf("Fin de la lecture du fichier à scanner.\n\n");
  if(ferror(fp)) printf("Erreur lors de la lecture du fichier à scanner.\n\n");
}

void read_lib(FILE* fp, Node* Tree)
{
  char word[MAX];
  while(1)
    {
      if(fscanf(fp, "%s", word)!=1)
	break;
      // printf("--%s--\n", word);
      //fflush(stdout);
      if(no_accent(word))
	add_in_tree(*Tree, word);
    } 
    if(feof(fp)) printf("Fin de la lecture de la bibliothèque.\n\n");
    if(ferror(fp)) printf("Erreur lors de la lecture de la  bibliothèque.\n\n");
}


void print_tree(Node Tree, int index)
{
  if(is_empty_tree(Tree))
    return;
  Node cpTree = NULL;
  cpTree = Tree;
  if(cpTree->next[index]==NULL && index<26)
    {
      print_tree(cpTree, index+1);
    }
  else if(index == 26)
    {
      return;
    }
  else
    {
      printf("%c\n", (cpTree->next[index])->letter);
      if((cpTree->next[index])->endWord)
  {
    printf("fin\n");
    //print_tree(cpTree, 0);
    return;
  }
      print_tree(cpTree->next[index], 0);
    }
}

int find_index(Node tree)
{
  Node cpTree = tree;
  int index = 0;
  while(cpTree->next[index]==NULL && index < NB_CARAC)
    index++;
  return index;
}

void print_first(Node Tree)
{
  Node cpTree = Tree;
  int index = 0;
  while(!is_leaf(cpTree) || !(cpTree->endWord))
    {
      index = find_index(cpTree);
      printf("%c\n", (cpTree->next[index])->letter);
      if(cpTree->next[index]->endWord) printf("fin\n");
      cpTree=cpTree->next[index];
    }
}

void free_tree(Node* Tree)
{
  if(*Tree!=NULL)
    {
      for(int i=0; i<NB_CARAC; i++)
	{
	  free_tree(&(*Tree)->next[i]);
	}
      free(*Tree);
    }
}