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 :

Problème utilisation fonction en boucle


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Mai 2007
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 10
    Par défaut Problème utilisation fonction en boucle
    Bonjour,

    Dans le cadre d'un programme, j'utilise plusieurs fonctions :

    La première fonction permet de parcourir un fichier, et de le lire ligne à ligne. Chaque ligne est de la forme 3 caractères pour un mois, un espace, 3 chiffres. ex : "jan 101"

    La deuxième fonction traite ces lignes de la façon suivante :
    on recupère la ligne, et selon le mois, on ajoute le chiffre de la ligne dans un fichier nommé : mois-datedelancement.txt
    La date fait 12 caracteres.
    ex d'un fichier: fev-070627180403.txt
    mois-AAMMJJHHMinMinSS.txt
    Si le fichier n'existe pas ( ce qui est le cas au lancement du programme ), il est crée.

    Après utilisation du programme, celui-ci plante. Il arrive à réaliser un appel à la fonction traite_ligne, mais la 2ème ligne n'est pas traitée.
    Il s'agit peut être d'un problème de mémoire ?

    Je vous remercie d'avance de votre aide,
    Isk

    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
     
    //fonction qui traite un fichier chemin est le chemin complet du fichier et
    //date est la date du lancement du programme
     
    void traite_fichier(char *chemin,char *date) {
     
        char ligne[256];
        FILE* fic;
     
        fic=malloc(sizeof(FILE));
    	fic=fopen(chemin,"r");    
        if ( fic == NULL ) { 
        printf("Erreur de lecture du fichier\n");
        return 0;
        }
     
         //on appelle ici la fonction traite_ligne en boucle jusqu'à ce qu'on ait plus 
         //de ligne
     
        while( fgets(ligne, sizeof ligne ,fic) != NULL )  {
          traite_ligne(ligne,date);
        }
     
        printf("\n");
        printf("%s a ete traite\n",chemin);
        fclose(fic);
        free(fic);
        free(ligne);
    }
     
     
     
     
    //fonction qui traite les lignes
    // char* sub_string(char* entree,int deb, int fin) 
    // est une fonction qui ressort les caracteres de entree[deb] à entree[fin]
     
    void traite_ligne(char * ligne,char * date) {
    	char nomfic[16];
    	FILE* fichier;
     
    	fichier= malloc(sizeof(FILE));
     
    	strcpy(nomfic,sub_string(ligne,0,2));
    	strcat(nomfic,"-");
    	strcat(nomfic,date);
    	strcat(nomfic,".txt");
     
        fichier=fopen(nomfic, "a");
    	fprintf(fichier,"%s\n",sub_string(ligne,4,6));
    	fclose(fichier);
     
    	free(nomfic);
    	free(fichier);
    }

  2. #2
    Membre habitué
    Inscrit en
    Mai 2007
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 10
    Par défaut
    Je viens de trouver, en fait l'espace alloué pour le nom du fichier n'etait pas suffisant, je n'avais pas pris en compte l'ajout du .txt

  3. #3
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par Iskander81
    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
    void traite_fichier(char *chemin,char *date) {
    
        char ligne[256];
        FILE* fic;
        
        fic=malloc(sizeof(FILE)); Ce malloc ne sert a rien !!!
        fic=fopen(chemin,"r");    
        if ( fic == NULL ) { 
        printf("Erreur de lecture du fichier\n");
        return 0;
        }
    
        [...]
    
        fclose(fic);
        free(fic); Ce free peut faire planter
        free(ligne); ligne est un tableau, le free n'est donc pas necessaire 
    }
    Meme remarques pour la deuxième fonction.

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    je dirais même plus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        free(fic); Ce free  plantera (variable (statique ??) gérée par fopen !!!
        free(ligne); ligne est un tableau, le free plantera !!!! 

  5. #5
    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 Iskander81
    Après utilisation du programme, celui-ci plante. Il arrive à réaliser un appel à la fonction traite_ligne, mais la 2ème ligne n'est pas traitée.
    Il s'agit peut être d'un problème de mémoire ?
    Tu utilises malloc() / free() à tord et à travers. Chaque usage doit être justifié... Ton code corrigé :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
     
    /* fonction qui traite les lignes */
    /* char* sub_string(char* entree,int deb, int fin) */
    /* est une fonction qui ressort les caracteres de entree[deb] à entree[fin] */
     
    char *sub_string (char *entree, int deb, int fin)
    {
       assert (fin >= deb);
       assert ((int)strlen (entree) >= fin);
       entree[fin] = 0;
       return entree + deb;
    }
     
    void traite_ligne (char *ligne, char const *date)
    {
       char nomfic[16];
     
       nomfic[sizeof nomfic - 1] = 0;
     
       strcpy (nomfic, sub_string (ligne, 0, 2));
       assert (nomfic[sizeof nomfic - 1] == 0);
       strcat (nomfic, "-");
       assert (nomfic[sizeof nomfic - 1] == 0);
       strcat (nomfic, date);
       assert (nomfic[sizeof nomfic - 1] == 0);
       strcat (nomfic, ".txt");
       assert (nomfic[sizeof nomfic - 1] == 0);
       {
          FILE *fichier = fopen (nomfic, "a");
     
          if (fichier != NULL)
          {
             printf ("nomfic*'%s'\n", nomfic);
     
             fprintf (fichier, "%s\n", sub_string (ligne, 4, 6));
             fclose (fichier);
          }
          else
          {
             perror (nomfic);
          }
       }
     
    }
     
    /* fonction qui traite un fichier chemin est le chemin complet du fichier et */
    /* date est la date du lancement du programme */
     
    int traite_fichier (char const *chemin, char const *date)
    {
       int err = 0;
       FILE *fic = fopen (chemin, "r");
       if (fic != NULL)
       {
          /* on appelle ici la fonction traite_ligne en boucle jusqu'à ce qu'on ait plus */
          /* de ligne */
          char ligne[256];
          while (fgets (ligne, sizeof ligne, fic) != NULL)
          {
             traite_ligne (ligne, date);
          }
     
          printf ("\n");
          printf ("%s a ete traite\n", chemin);
          fclose (fic);
       }
       else
       {
          printf ("Erreur de lecture du fichier\n");
          err = 1;
       }
       return err;
    }
     
    int main (void)
    {
       traite_fichier ("test.txt", "01/01/07");
       return 0;
     
    }
    Pose des questions si tu ne comprends pas.

  6. #6
    Membre habitué
    Inscrit en
    Mai 2007
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 10
    Par défaut
    je comprend pas très bien l'usage de la fonction assert...
    je crois avoir saisi que c'est une fonction de controle, prenant une expression logique en entrée.
    Pour la fonction sub_string corrigée, j'ai du mal à saisir comment le retour fonctionne... on retourne chaine + deb ? ( char * + int ? ) en sachant qu'on ne veut qu'une sous partie de chaine ?

    merci pour vos conseils, j'ai réalisé les modifications en otant les malloc et free à outrance.

    isk

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    assert() est une macro qui sert à vérifier tout ce qui ne dépend d'aucun facteur extérieur, tout ce qui doit toujours être vrai.

    Si une assertion échoue, on sait que c'est le programmeur qui est à blâmer. Et non pas l'OS, ni l'utilisateur.

    Donc ici, si tu appelles la fonction sub_string avec fin inférieur à deb, ou avec fin supérieur à la taille de la chaîne, ça geulera (en mode Debug uniquement) et ce sera ta faute.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    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 Iskander81
    je comprend pas très bien l'usage de la fonction assert...
    je crois avoir saisi que c'est une fonction de controle, prenant une expression logique en entrée.
    http://emmanuel-delahaye.developpez....tes.htm#assert
    Pour la fonction sub_string corrigée, j'ai du mal à saisir comment le retour fonctionne... on retourne chaine + deb ? ( char * + int ? ) en sachant qu'on ne veut qu'une sous partie de chaine ?
    Comme tu n'as pas donné le code de cette fonction, j'en ai bricolé une vite fait à partir du prototype supposé... Ca ne prétend pas être une 'correction' de la tienne.

  9. #9
    Membre habitué
    Inscrit en
    Mai 2007
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 10
    Par défaut
    D'accord.. Encore merci de vos conseils et de vos réponses ! Je tache de m'en imprégner pour ne plus faire les mêmes erreurs.

    Isk

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 11/03/2010, 16h24
  2. Problème utilisation fonction javascript en c#
    Par xavpiaf dans le forum ASP.NET
    Réponses: 2
    Dernier message: 18/06/2008, 16h47
  3. [STL] Débutant : problème utilisation fonction Sort
    Par marcootz dans le forum SL & STL
    Réponses: 5
    Dernier message: 29/08/2007, 20h19
  4. problème utilisation fonction openSSL
    Par sneb5757 dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 30/04/2007, 16h49
  5. [Mail] problème utilisation fonction mail()
    Par leclone dans le forum Langage
    Réponses: 3
    Dernier message: 20/02/2007, 18h05

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