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 :

Parsing de fichier


Sujet :

C

  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut Parsing de fichier
    Bonjour.

    Je voudrai écrire dans un fichier texte toutes les lignes d'un aute fichier texte qui comportent une occurence bien précise (séquence de caractère particuière).

    Je me suis souvenu que ce problème était traité dans le bouquin "Le Langage C" de Kernighan et Ritchie, mais ils utilisent une macro qui définit la longueur maximale acceptable des lignes (en un sens ça protège des segfaults)
    Je voulais savoir si c'était vraiment le seul moyen de faire ça, c'est à dire sans gets, mais sans non plus passer de longueur de ligne maximale.

    En fait, même si la mémoire est allouée, la chaîne lue par fgets se termine tout de même au caractre \0. Donc on peut utiliser strlen et faire une recopie sans risque en allouant un unique grand buffer pour chaque ligne du fichier lu.

    Donc pas de problème en fait Merci. Peut être que j'aurai une autre question après.

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    Je voudrai écrire dans un fichier texte toutes les lignes d'un aute fichier texte qui comportent une occurence bien précise (séquence de caractère particuière).

    Je me suis souvenu que ce problème était traité dans le bouquin "Le Langage C" de Kernighan et Ritchie, mais ils utilisent une macro qui définit la longueur maximale acceptable des lignes (en un sens ça protège des segfaults)
    Je voulais savoir si c'était vraiment le seul moyen de faire ça, c'est à dire sans gets,<...>
    gets() ne sait pas lire des lignes (ou alors il faut rediriger l'entrée). De toutes façons, il ne faut pas utiliser cette fonction, elle est dangereuse.

    Tu parles peut être de fgets() ?

    Sinon, tu veux un moyen de lire un ligne de longueur quelconque ? Il y a un exemple opérationnel ici :

    http://www.developpez.net/forums/sho...7&postcount=17

    facile à adapter à une lecture fichier... C'est basé sur fgetc() et malloc()/realloc().

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Oui, gets est pour le flux standard, pardon, finalement j'ai utilisé fgets sur un flux de fichier avec une longueur maximale de 1000 pour le buffer intermédiaire, longueur qui est donc précisée dans la fonction pour éviter tout dépassement. Comme j'ai de la chance, l'occurence que je cherche se trouve dans les lignes concernées systématiquement au début de la ligne.
    J'utilise donc strncmp qui est parfaite pour comparer les n premiers caractères de deux chaînes.

    J'ai une petite difficulté maintenant au sujet de la réécriture de la ligne contenant l'occurence, je ne sais pas comme faire avec fprintf car cette fonction ne prend que des const char *. Suis-je obligé de faire une nouvelle allocation à chaqe fois que je trouve une occurence ou est-ce que je peux détruire le const char * avec free et lui réallouer une zone mémoire non utilisée avec malloc() ?

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    J'ai une petite difficulté maintenant au sujet de la réécriture de la ligne contenant l'occurence, je ne sais pas comme faire avec fprintf car cette fonction ne prend que des const char *. Suis-je obligé de faire une nouvelle allocation à chaqe fois que je trouve une occurence ou est-ce que je peux détruire le const char * avec free et lui réallouer une zone mémoire non utilisée avec malloc() ?
    Tu peux recopier la ligne directement. Il n'y a rien à allouer. Tu peux même utiliser fputs(), c'est encore plus simple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       char line[BIG_ENOUGH];
       while (fgets (line, sizeof line, fp_in) != NULL)
       {  
          char const s_ref[] = "bozo";
          if (strncmp (line, s_ref, sizeof s_ref - 1) == 0)
          {
             fputs(line, fp_out);
    tout simplement...

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Oua !
    Merci beaucoup, c'est génial. Merci beaucoup, je m'en souviendrai.
    [EDIT]Ah oui, mais ... int fputs(const char *s, FILE *stream); Il prend un const char *. Je vais mettre un cast.

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Je n'arrive pas à faire fonctionner ce code. Avec -Wall -pedantic, je n'ai pas de warnings mais un résultat vraiment inutile et une erreur de double free à l'exécution. Pouvez vous m'aider à y voir plus clair ? Merci beaucoup.
    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
    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 <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #define LENGTHMAX 1000
     
     
     
     
    int main(int argc, char **argv)
    {
      const char debutchaine[] = "occurence";
      char * buffer_subtitle=NULL;
      char * filenametrad_transitoire = NULL;
      const char * filename = NULL;
      const char * filename_dest = NULL;
      char line_buffer[1000];
     
      size_t arglength = strlen(argv[1]);
      /*On recupere la longueur de l'argument*/
     
      FILE * monfichier = NULL;
      FILE * monfichier_dest = NULL; 
      /*déclaration des pointeurs sur flux de fichier*/
     
      /*recopie du nom de fichier*/
      filename = malloc(arglength+1);
      if(filename==NULL)
        printf("erreur d'allocation memoire pour la recopie de l'argument 1\n");
     
      filename = argv[1] ; 
      /*recopie du nom de fichier*/
     
     
      printf("extraction des dialogues du fichier : %s\n",filename);  
     
      filenametrad_transitoire = calloc(arglength+5,1);
      filename_dest = malloc(arglength+5);
      if(filename_dest==NULL || filenametrad_transitoire==NULL)
        printf("erreur d'allocation memoire sur l'extension de nom de fichier\n");
     
      strncpy(filenametrad_transitoire, filename, arglength+1);
      /*arglength+1 pour inclure le caractere de fin de chaine*/
     
      strncat(filenametrad_transitoire, ".out", 4);
      filename_dest=filenametrad_transitoire;
     
      printf("le nom du fichier de sortie est %s\n",filename_dest);
     
      free(filenametrad_transitoire);
      filenametrad_transitoire=NULL;
     
      monfichier  = fopen( filename , "r" );
      if(monfichier==NULL)
        {
        printf("echec a l'ouverture en lecture seule du fichier\n");
        }
     
      monfichier_dest = fopen( filename_dest, "w" );
      if(monfichier_dest==NULL)
        {
        printf("erreur d'ouverture en ecriture du fichier de destination\n");
        }
     
    /*Boucle d'analyse et d'ecriture dans le fichier ds sous-titre*/
     
      do
        {
        if(strncmp(line_buffer,debutchaine,8)==0)
          {
     
          buffer_subtitle=malloc(strlen(line_buffer)+1);
          if(buffer_subtitle==NULL)
            printf("erreur d'allocation memoire pour le buffer contenant le sous-titre\n");
          strcpy(buffer_subtitle,line_buffer);
     
          printf("on a la chaine :\n%s\npour sous-titre\n", buffer_subtitle);  
          fputs( (const char *)buffer_subtitle, monfichier_dest );
          fputs( "\n", monfichier_dest);
     
          }
        free(buffer_subtitle);
        }while(fgets(line_buffer, LENGTHMAX-1, monfichier)!=NULL);
     
     
      free(line_buffer);
      fclose(monfichier_dest);
      fclose(monfichier);
     
      return 0;
    }

  7. #7
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Emmanuel sort sa fonction :

    "Sinon, tu veux un moyen de lire un ligne de longueur quelconque ? Il y a un exemple opérationnel ici :"

    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
    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
     
    char *lecture_clavier (void)
    {
       char *texte = NULL;
       size_t taille_buffer = 1;
     
       texte = malloc (sizeof *texte * taille_buffer);
       if (texte != NULL)
       {
          size_t i = 0;
          int c;
     
          /* verification du tableau */
          texte[taille_buffer-1] = 0;
     
          while ((c = getchar ()) != '\n' && c != EOF && texte != NULL)
          {
          /* verification du tableau */
             assert (texte[taille_buffer-1] == 0);
             texte[i] = c;
             i++;
             if (i == taille_buffer)
             {
                char *tmp = realloc (texte, sizeof *texte * (taille_buffer * 2));
     
                if (tmp != NULL)
                {
                   texte = tmp;
                   taille_buffer *= 2;
                   /* verification du tableau */
                   texte[taille_buffer-1] = 0;
                }
                else
                {
                   free (texte), texte = NULL;
                }
             }
          }
     
          if (c != EOF)
          {
             texte[i] = 0;
             /* verification du tableau */
             assert (texte[taille_buffer-1] == 0);
          }
          else
          {
             free (texte), texte = NULL;
          }
     
       }
       return texte;
    }
    Elle est truffée de "assert" et ne prévoit pas les exceptions en cas de dépassement de la capacité mémoire suite à l'évocation de "realloc".

    De plus, "taille_buffer" va retourner une valeur négative si on excède la valeur maximale de "size_t'.

  8. #8
    Membre éprouvé
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Par défaut
    Citation Envoyé par dj.motte
    Elle est truffée de "assert"
    tu peux développer? t'as quoi contre les assert?

    et ne prévoit pas les exceptions en cas de dépassement de la capacité mémoire suite à l'évocation de "realloc".
    et le test sur le retour de realloc, c'est pour la déco donc?

    De plus, "taille_buffer" va retourner une valeur négative si on excède la valeur maximale de "size_t'.
    pourquoi ce serais négatif?
    lire le prototype des fonctions !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
           void *realloc(void *ptr, size_t size);

  9. #9
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *tmp = realloc (texte, sizeof *texte * (taille_buffer * 2));
    Que se passe t il si "taille_buffer * 2" déborde la capacité d'un "size_t" ?

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    Je n'arrive pas à faire fonctionner ce code.
    Ce code est beaucoup trop compliqué pour être correct.

    Il faut décomposer les opérations en opération élémentaires. Par exemple, fabriquer le nom du fichier de destination à partir du nom du fichier source est une bonne idée, mais c'est un problème annexe qui ne doit pas polluer le programme principal.

    Ensuite, il y a quelques principes de base qu'il faut connaitre, à savoir que lorsqu'on ouvre un fichier, si la réponse est NULL, il ne faut pas contenter d'un message, mais surtout ne plus effectuer aucune opération sur le fichier.

    L'algorithme canonique est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
       FILE *fp = fopen (fname, MODE);
       if (fp != NULL)
       {
          /* operations sur le fichier. */
     
     
          fclose (fp), fp = NULL;
       }
       else
       {
          perror (fname);
       }
    Si on manipule 2 fichiers, l'ensemble de cet algorithme est placé une 2ème fois dans le premier :

    Exemple typique :

    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
     
       FILE *fp_in = fopen (fname_in, "r");
       if (fp_in != NULL)
       {
          FILE *fp_out = fopen (fname_out, "w");
          if (fp_out != NULL)
          {
             /* operations sur les fichiers. */  
     
     
             fclose (fp_out), fp_out = NULL;
          }
          else
          {
             perror (fname_out);
          }
          fclose (fp_in), fp_in = NULL;
       }
       else
       {
          perror (fname_in);
       }
    Il n'y a pas de raison d'écrire du code plus complexe que ça. Bien respecter la structure du code et la présentation (indentation) et le nommage des variables. Le traitement peut faire l'objet d'une fonction séparée (avec 2 paramètres FILE *).

  11. #11
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte
    Salut,

    dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *tmp = realloc (texte, sizeof *texte * (taille_buffer * 2));
    Que se passe t il si "taille_buffer * 2" déborde la capacité d'un "size_t" ?
    Il prend une valeur comprise entre 0 et (size_t) -1. Un size_t est un entier non signé.

    C'est pas dangereux, mais ça peu surprendre...

    Je t'autorise à ajouter le code qui détecte cette condition et qui retourne NULL proprement. (c'est à dire sans sagouiner ma fonction à coup de return ou de exit() à la barbare).

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte
    Elle est truffée de "assert"
    As-tu au moins compris à quoi ils servaient ?

    Je rappelle qu'en production (release), les assert() ne sont pas compilés. Il ne m'ont servi qu'en debug à mettre au point la fonction, car il n'est pas évident de gérer correctement la taille quand on a affaire à une chaine de caractère avec son 0 final...

    Normalement, j'utilise mes macros LIM_PTR() et CHK_PTR() de

    http://emmanuel-delahaye.developpez....b/ed/inc/sys.h

    Mais si tu as une meilleure méthode, surtout ne te gènes pas.

  13. #13
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Voilà, j'ai fait une fonction dédiée FILE * ouvre_trad(const char * nom_original) :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    FILE * ouvre_trad(const char * nom_original)
         {
     
         FILE * p_flux_trad = NULL;
         char * nom_trad = NULL
         size_t name_length;
     
         name_length = strlen( nom_original );
         nom_trad = malloc( name_length+5 );
         if(nom_trad==NULL)
              printf("erreur d'allocation memoire sur la chaine nom_trad\n");
     
         strncpy(nom_trad, nom_original, name_length+1);
         printf("Le nom du fichier original est %s\n",nom_original);
     
         strcat(nom_trad, ".out");
         printf("le nom du fichier de sortie est %s\n",nom_trad);
     
         p_flux_trad = fopen(nom_trad, "w");
     
         if(p_flux_trad==NULL);
              {
              printf("erreur allocation memoire sur p_flux_trad\n");
              return NULL;
              }
         else
              {
              return p_flux_trad;
              }
     
         }

  14. #14
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    Voilà, j'ai fait une fonction dédiée FILE * ouvre_trad(const char * nom_original) :
    Je ne sais pas pourquoi je perds mon temps à expliquer comment faire le découpage du code si tu fais autre chose...

  15. #15
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Ça marche. Merci beaucoup Emmanuel Delahaye. Voilà ce que j'ai fait :
    Copie de fichier
    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
    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #define LENGTHMAX 1000
     
     
    char * nom_cible(const char *);
     
    int main(int argc, char **argv)
         {
     
         FILE * p_source;
         FILE * p_cible;
     
         char * fname_trad;
         char * fname_source;
     
         char * line_buffer;
         line_buffer = malloc(LENGTHMAX);
     
         fname_trad = nom_cible(argv[1]);
         fname_source=argv[1];
     
         p_source = fopen(fname_source, "r");
         if(p_source!=NULL)
              {
              p_cible = fopen(fname_trad,"w");
              if(p_cible!=NULL)
                   {
                   while(fgets(line_buffer, LENGTHMAX, p_source)!=NULL)
                        {
                        fputs(line_buffer, p_cible);
                        }
                   free(line_buffer);
                   fclose(p_cible);
                   p_cible=NULL;
                   }
              else
                   {
                   perror(fname_trad);
                   }
              fclose(p_source);
              p_source=NULL;
              }
         else
              {
              perror(fname_source);
              }
         return 0;
         }          
     
     
     
     
    char * nom_cible(const char * nom_original)
         {
     
         char * nom_trad = NULL;
         size_t name_length;
     
         name_length = strlen( nom_original );
         nom_trad = malloc( name_length+5 );
         if(nom_trad==NULL)
              {
              printf("erreur d'allocation memoire sur la chaine nom_trad\n");
              return NULL;
              }
         else
              {
              strncpy(nom_trad, nom_original, name_length+1);
              printf("Le nom du fichier original est %s\n",nom_original);
              strcat(nom_trad, ".out");
              printf("le nom du fichier de sortie est %s\n",nom_trad);
              return nom_trad;
              }
     
         }
    Est-ce qu'il est utile de libérer la mémoire allouée dans des fonctions externes au main ?

    Maintenant, pour les tests, je voudrai utiliser strncmp, est ce que c'est une bonne idée ?

  16. #16
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    Ça marche. Merci beaucoup Emmanuel Delahaye. Voilà ce que j'ai fait :
    Encore un peu trop compliqué. Je conseille de gérer les variables au plus près de leur besoin :
    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
    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
    static char *nom_cible (const char *nom_original)
    {
    #define EXT ".out"
       size_t name_length = strlen (nom_original);
     
       char *nom_trad = malloc (name_length + sizeof EXT);
       if (nom_trad == NULL)
       {
          printf ("erreur d'allocation memoire sur la chaine nom_trad\n");
       }
       else
       {
          strcpy (nom_trad, nom_original);
          printf ("Le nom du fichier original est %s\n", nom_original);
          strcat (nom_trad, EXT);
          printf ("le nom du fichier de sortie est %s\n", nom_trad);
       }
       return nom_trad;
    #undef EXT
    }
     
    static void usage (void)
    {
       puts ("USAGE monappli monfichier");
    }
     
    int main (int argc, char **argv)
    {
       if (argc > 1)
       {
          char *fname_source = argv[1];
          char *fname_trad = nom_cible (fname_source);
          if (fname_trad != NULL)
          {
             FILE *p_source = fopen (fname_source, "r");
             if (p_source != NULL)
             {
                FILE *p_cible = fopen (fname_trad, "w");
                if (p_cible != NULL)
                {
                   char line[1000];
                   while (fgets (line, sizeof line, p_source) != NULL)
                   {
                      fputs (line, p_cible);
                   }
                   fclose (p_cible), p_cible = NULL;
                }
                else
                {
                   perror (fname_trad);
                }
                fclose (p_source), p_source = NULL;
             }
             else
             {
                perror (fname_source);
             }
             free (fname_trad), fname_trad = NULL;
          }
       }
       else
       {
          usage ();
       }
       return 0;
    }
    Pose des questions si tu ne comprends pas.
    Copie de fichier
    <...>
    Est-ce qu'il est utile de libérer la mémoire allouée dans des fonctions externes au main ?
    Tout ce qui a été alloué doit être libéré.
    Maintenant, pour les tests, je voudrai utiliser strncmp, est ce que c'est une bonne idée ?
    C'est même tout à fait indiqué. J'avais indiqué comment faire, non ?

  17. #17
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Oui. Cela fonctionne à présent. J'ai beaucoup appris lors de cet exercice. Je vous remercie de votre aide.

    (la remarque du type fatigué de parser ses fichiers textes avec du C : quoiqu'utiliser grep aurait été plus rapide)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Parsing de fichier XML en C
    Par longbeach dans le forum XML
    Réponses: 12
    Dernier message: 12/12/2006, 16h31
  2. Parsing gros fichier performant ?
    Par jaggy19 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 09/11/2006, 13h11
  3. parsing de fichier texte
    Par robert_trudel dans le forum Access
    Réponses: 4
    Dernier message: 03/06/2006, 17h45
  4. [DOM] [DocumentBuilder] Problème de parsing de fichier
    Par tck-lt dans le forum Format d'échange (XML, JSON...)
    Réponses: 9
    Dernier message: 13/04/2006, 17h18
  5. Parsing de fichier en C++ : Au secours :(
    Par Triqueur dans le forum C++
    Réponses: 4
    Dernier message: 16/02/2006, 14h49

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