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 :

probleme dans l'ecriture d'un fichier texte


Sujet :

C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 68
    Points : 31
    Points
    31
    Par défaut probleme dans l'ecriture d'un fichier texte
    Bonjour,

    j'ai un problème, je veux faire un petit programme qui va lire un texte et baliser chaque pronom personnel rencontré dans le texte de balises <pp></pp>.

    Pour ce faire, j'ouvre mon fichier test.txt qui contient le fichier texte à traiter, et je crée un fichier hey.xml qui va contenir le texte formaté (avec les balises).

    Tant qu'on est pas arrivé à la fin du fichier test.txt :

    tant que le caractère donné par getc n'est pas un espace ou saut de ligne, on copie ce caractère dans un tableau motlu.

    On copie enfin le tableau motlu dans le tableau temp, et on convertit en minuscule les caractères present dans le tableau temp.

    On compare le mot présent dans le tableau temp à notre base de données (qui contient tous les pronoms personnels du français), si le mot du tableau temp est contenu dans la base, donc si on a enregistré un pronom personne, on ecrit la balise <pp> dans notre fichier xml, suivit des données du tableau motlu (j'ecris les données du tableau motlu et non ceux du tableau temp car je veux conserver les majuscules du texte), et je mets la variable ok à 1 pour indiquer que le mot a bien été balisé.

    Si ok vaut 0 , donc qu'il ne faut pas baliser le mot car on ne l'a pas trouvé dans la base de donnée, alors on l'ecrit directement à la suite dans le fichier xml.


    Voilà comment fonctionne mon programme.

    Le problème est que quand j'execute mon programme et que je lis le fichier xml, il y a bcp de mots qui sont recopiés, en gros si dans mon fichier test.txt il y a par exemple : "Ceci est juste un test." il y aura dans mon fichier xml un truc du style : "Ceci estci juste unte test."

    Bref, je pense que lorsque j'enregistre les caratères dans mon tableau il enregistre en même temps des trainées en mémoire et je ne comprend pas comment cela se fait, car après chaque mot ecrit, j'utilise la fonction bzero à mon tableau.

    Si qqn aurait une idée...

    Merci d'avance

    Code C : 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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
     
    void liremot(FILE *fichier,FILE *fichier2,char *motlu,int *finfichier,char base_donnee[][5]);
     
    int main (void) {
     
      FILE *fichier=NULL;
      FILE *fichier2=NULL;
     
      char *motlu;
      char base_donnee[18][5]={"je","tu","il","elle","on","nous","vous","ils","elles"};
      int finfichier=0;
     
      motlu=(char *)malloc(30*sizeof(char));
     
      fichier=fopen("test.txt","r+");
      fichier2=fopen("hey.xml","w+");
     
      if(fichier2==NULL)
        {
          printf("Erreur lors de la creation du fichier\n");
          exit(0);
        }
     
      if(fichier==NULL) 
        {
          printf("Erreur lors de l'ouverture du fichier\n");
          exit(0);
        }
      else
        {
          while(!finfichier)
    	{
    	  liremot(fichier,fichier2,motlu,&finfichier,base_donnee);
    	  bzero(motlu,sizeof(motlu));
    	}
        }
     
      fclose(fichier);
      fclose(fichier2);
     
      return 0;
    }
     
    void liremot(FILE *fichier,FILE *fichier2,char *motlu,int *finfichier,char base_donnee[][5]) {
     
      char car_lu=' ';
      int i=0,ok=0;
      char *temp;
     
      temp=(char *)malloc(30*sizeof(char));
     
      while((car_lu=getc(fichier))!=' ' && car_lu!='\n') 
        {
          if(car_lu==EOF)
    	{
    	  *finfichier=1;
    	  return;
    	}
          else
    	{
    	  motlu[i]=car_lu;
    	  i++;
    	}
        }
     
      for(i=0;i<30;i++)
        {
          temp[i]=motlu[i];
          if(isalpha(temp[i]))
    	temp[i]=tolower(temp[i]);
        }
     
      for(i=0;i<18;i++)
        {
          if(strcmp(temp,base_donnee[i])==0)
    	{
    	  fputs("<pp>",fichier2);
    	  fprintf(fichier2,"%s",motlu);
    	  fputs("</pp> ",fichier2);
    	  ok=1; /* ok vaut 1 lorsque le mot a été balisé, si il vaut 0, on ecrit le mot directement sans le baliser*/
    	  break;
    	}
        }
      if(!ok)
        fprintf(fichier2,"%s ",motlu);
    }

  2. #2
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Quelques remarques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while(!finfichier)
    {
      liremot(fichier,fichier2,motlu,&finfichier,base_donnee);
      bzero(motlu,sizeof(motlu));
    }
    1- Le tableau pointé par motlu n'est pas initialisé à 0 au moment du premier appel à liremot

    2- sizeof(motlu) donne la taille de la variable motlu. Celle-ci est un pointeur et on obtient la taille d'un pointeur (typiquement 4) et non pas la taille du tableau. Le tableau n'est donc pas totalement initialisé et la chaîne obtenue n'est pas correctement terminée par '\0' -> erreur constatée.

    3- La fonction liremot devrait renvoyer dans motlu une chaîne correctement formée, sans laisser à la fonction appelante le soin d'initialiser le tableau à zéro. Une fonction doit faire une tâche complètement et fournir un résultat correct.
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      while((car_lu=getc(fichier))!=' ' && car_lu!='\n') 
      {
    ....
      }
      motlu[i]= '\0' ; // place le zéro terminant la chaîne
    4- Pourquoi utiliser la liste des paramètres de la fonction pour renvoyer l'information de fin de fichier ? On peut utiliser la valeur de retour de la fonction.
    Par exemple :
    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
     
    int liremot(FILE *fichier,FILE *fichier2,char *motlu,char base_donnee[][5])
    {
    ....
      while((car_lu=getc(fichier))!=' ' && car_lu!='\n') 
      {
        if(car_lu==EOF) return 0;
    ....
      }
    ....
      return 1;
    }
    // Dans main :
    ....
      else
        while(liremot(fichier,fichier2,motlu,base_donnee)) { }   
    ...
    5- La fonction liremot alloue de la mémoire (temp) mais ne la libère pas -> fuite de mémoire.
    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
     
    .... liremot(......)
    { 
      char car_lu=' ';
      int i=0,ok=0;
      char *temp;
     
      while((car_lu=getc(fichier))!=' ' && car_lu!='\n') 
      {
    ....
      }
      temp= malloc(30); // inutile d'allouer plus tôt
      if(temp != NULL) // tester si l'allocation a réussi
      {
    ....
         free(temp);
      }
     else 
      {
    ....
      }
    }
    D'ailleurs, pourquoi utiliser un tableau supplémentaire temp, plutôt que faire ce qu'il faut directement dans motlu ?

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 329
    Points : 36 848
    Points
    36 848
    Par défaut eppur si mueve!
    Vous imprimez le contenu de temp qui est réalloué à chaque passage mais malloc n'est pas calloc: vous aurez toujours un buffer "sale".
    Ceci dit, il ne suffira pas de remplacer malloc par calloc pour que cela fonctionne.

    Dans liremot, ca commence par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      while((car_lu=getc(fichier))!=' ' && car_lu!='\n') 
        {
          if(car_lu==EOF)
    	{
    	  *finfichier=1;
    	  return;
    	}
          else
    	{
    	  motlu[i]=car_lu;
    	  i++;
    	}
        }
    On sort du while lorsque car_lu dans {'\n', ' '}.
    Les caractères significatifs du mot lu qui sont dans motlu[0..i]
    Dit autrement, la valeur de i donne la longueur du mot lu.

    Malheureusement vous n'en faites pas grand chose.

    La suite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      for(i=0;i<30;i++)
        {
          temp[i]=motlu[i];
          if(isalpha(temp[i]))
    	temp[i]=tolower(temp[i]);
        }
    Est ce que les caractères significatifs de motlu sont ceux de [0..30]???
    Puisque vous faites cela en C, pourquoi ne pas terminer motlu par un 0... Et vous baser sur cela pour détecter la fin du mot?
    Ca pourrait donner:
    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
      while((car_lu=getc(fichier))!=' ' && car_lu!='\n') 
        {
          if(car_lu==EOF)
    	{
    	  *finfichier=1;
    	  return;
    	}
    	motlu[i]=car_lu;
    	i++;
        }
        motlu[i] = 0;
    /** puis... **/
        for (i = 0; motlu[i] != 0; i++)
             temp[i] = tolower(motlu[i]);
    // sans oublier de faire
         temp[i] = 0;
    Car sprintf réclamera une chaine terminée par 0....
    -W
    PS: Grilled et il est vrai que j'ai omis de parler du free...

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 68
    Points : 31
    Points
    31
    Par défaut
    Merci pour toutes vos explications judicieuses, j'ai bien compris le probleme maintenant et les choses qui n'allaient pas dans mon code.

    Par contre juste une question :

    D'ailleurs, pourquoi utiliser un tableau supplémentaire temp, plutôt que faire ce qu'il faut directement dans motlu ?
    En faite j'utilise un tableau supplémentaire, car je veux comparer le motlu converti en minuscule avec ma base de donnée, mais lorsque j'ecris mon motlu je veux l'ecrire de la même maniere qu'il etait typographié dans le texte.

    Exemple si dans mon texte, j'ai :

    Je vis ici.

    je veux pouvoir comparer "Je" avec ma base de donnée, c'est pour ça que je la convertis en minuscule, mais je veux bien écrire "Je" et non pas "je" dans mon texte.

    Si vous avez une autre solution plus propre, je suis à l'ecoute.

    Merci d'avance.

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    D'ailleurs, pourquoi utiliser un tableau supplémentaire temp, plutôt que faire ce qu'il faut directement dans motlu ?
    En faite j'utilise un tableau supplémentaire, car je veux comparer le motlu converti en minuscule avec ma base de donnée, mais lorsque j'ecris mon motlu je veux l'ecrire de la même maniere qu'il etait typographié dans le texte.
    Ok. Mille excuses. Une erreur d'inattention de ma part

Discussions similaires

  1. Erreur E/S 105 lors d'ecriture avec un fichier text
    Par Andry dans le forum Langage
    Réponses: 5
    Dernier message: 20/02/2009, 11h29
  2. [debutant] sauter une ligne dans l'ecriture d'un fichier
    Par nadhem dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 09/08/2006, 09h51
  3. Réponses: 5
    Dernier message: 20/03/2006, 12h35
  4. recuperer 3 float dans une ligne d'un fichier texte
    Par obiwankennedy dans le forum C++
    Réponses: 3
    Dernier message: 14/03/2006, 03h59
  5. [VB]recherche dans une partie d'un fichier texte
    Par malhivertman1 dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 19/01/2006, 11h56

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