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 :

Récupération de données structurées dans un fichier


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 10
    Points : 7
    Points
    7
    Par défaut Récupération de données structurées dans un fichier
    Bonjour j'ai une question concernant la récupération de donnée structuré dans un fichier, je n'ai pas eu de souçi pour le fwrite mais pour le fread la fenêtre s'ouvre puis se ferme immédiatement malgré le systeme("pause"), je ne peut donc pas savoir à l'aide du printf si les données ont bien été récupérées.
    voici le code:
    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
     
    #include <conio.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(int argc, char *argv[])
    {
        FILE *sp=fopen("spectacle.dat","r+b"); /*fichier contenant le nombre d'events*/
        FILE *pe=fopen("event.dat","r+b");     /*fichier ou l'on saisie les events*/
     
        fseek(pe,0,SEEK_SET);  
        fseek(sp,0,SEEK_SET);  
     
        int i, tot_event;
     
        struct evenement
        {
            char show [30];                /*structure event*/
            int mois;
            int jour;
        };
     
        evenement actu[tot_event];
     
        if (sp != NULL)
        {  
            fread(&tot_event,sizeof(int), 1, sp);
            printf("%d",tot_event);
            fclose(sp);
        }      
     
        if (pe != NULL)
        {   
            /*les données ont été saisie avec un fwrite*/
            for(i=1;i<tot_event;i++)
            {
                fread(&actu[i],sizeof(struct evenement), 1, pe);
                printf("%s %d %d",actu[i].show, actu[i].mois, actu[i].jour);
            }
     
            fclose(pe);          
        }
     
        system("PAUSE");
        return 0;
    }

    si quelqu'un a une idée... merci d'avance :-)

  2. #2
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Plusieurs remarques:

    * Tu utilises les fichiers (fonction fseek) sans vérifier que l'ouverture c'est bien déroulée.
    * Tu crées un tableau de tot_event éléments alors que la variables tot_event n'est pas initialisée.
    * Au passage tu crées un tableau dont la taille est une variable. Ton programme utilises donc les VLAs (définis par C99 mais pas encore correctement supportés par tous les compilateurs) ou une extension propriétaire de ton compilateur.
    * Tu ne teste pas le résultat de fread(), si une lecture se passe mal (fichier mal formaté, etc.) ton programme continue quand même.

    En outre l'écriture ou la lecture directe de structure dans un fichier peut poser des problèmes et doit être utilisée avec précaution. En effet, le padding dans la structure (et donc sa taille et la position exacte des éléments dans celle-ci) va dépendre du compilateur, de sa version, des options de compilation, etc.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Salut gl, j'ai tenu compte de tes remarques, j'ai enlevé la boucle for pour y voir plus clair, mis en place les différents vérificateurs d'erreurs, mais ça me donne toujours le même résultat.
    Mon compilateur c'est Dev-c++ et il gère les variables dans un tableau.
    Maintenant il m'indique erreur d'ouverture...
    Ce que je voudrais surtout savoir comment stocker correctement des données structures dans un fichiers et être sur de les retrouver?
    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
     
    #include <conio.h>
    #include <stdlib.h>
    #include <stdio.h>
     
     
    int main(int argc, char *argv[])
    {
        FILE* sp = NULL;
        FILE* pe = NULL;
     
        sp=fopen("spectacle.dat","r+b"); 
        pe=fopen("event.dat","r+b");     /*fichier ou l'on saisie les events*/
     
        int i, tot_event;   /*i et tot_event sont initialisées*/
     
     
        struct evenement
        {
        char show [30];                /*structure event*/
        int mois;
        int jour;
        int place_reserve[50][60];   
        };
     
    if (errno==0)   
      {  
        if (sp != NULL)
        {  
     
                 fseek(sp,0,SEEK_SET);  
                 fread(&tot_event,sizeof(int), 1, sp);
                 printf("%d",tot_event);
                 fclose(sp);
        }       
     
    evenement actu[tot_event];  /*structure chargé*/
     
     
        if (pe != NULL)
        {   
            fseek(pe,0,SEEK_SET);  
            fread(&actu[1],sizeof(struct evenement), 1, pe);
            printf("%s %d %d",actu[1].show, actu[1].mois, actu[1].jour);
     
        }
        fclose(pe);
     
    }else perror("erreur ouverture");    
     
    system("PAUSE");
     
       return 0;
    }

  4. #4
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par magicland Voir le message
    j'ai enlevé la boucle for pour y voir plus clair, mis en place les différents vérificateurs d'erreurs, mais ça me donne toujours le même résultat.
    Mon compilateur c'est Dev-c++ et il gère les variables dans un tableau.
    Maintenant il m'indique erreur d'ouverture...
    Pourquoi tester errno ici ? Le test pour savoir si l'ouverture d'un fichier s'est bien déroulé consiste à tester la valeur de retour, ce que tu fais d'ailleurs correctement avant d'utiliser les fichiers.

    Pourquoi ouvres-tu les fichiers en mode r+ alors que tu ne fais que les lire ? r suffit.

    Pourquoi utilises-tu actu[1] pour lire le premier élément et non actu[0] ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    finalement ca s'ouvre et sa reconnait bien la structure mais avec les mauvaise valeurs, sa m'affiche 0 0 0 au lieu de fete 23 2 (par exemple)

    Le erno est plus pratique pour détecter les erreurs d'ouverture, tu me dis que ca fait doublon donc je le supprime tous comme le r+ effectivement (quoique pour ce dernier il faut que le compilateur détecte direct que c'est du binaire et non du texte, d'après ce que j'ai compris c'est par défaut..)

    Ensuite pour le actu[1] au lieu du actu[0] je ne crois pas que c'est une incidence sur le code, j'y vois plus clair mais je perd une unité de stockage.

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par magicland Voir le message
    Le erno est plus pratique pour détecter les erreurs d'ouverture, tu me dis que ca fait doublon donc je le supprime
    Plus pratique oui et non. Mais surtout il faut l'utiliser correctement : errno n'est mis à jour qu'en cas d'erreur (donc si fopen renvoie NULL) s'il n'y a pas eu d'erreur la valeur est indéterminé, à moins d'avoir initialisé errno avant l'appel de la fonction.

    Le rôle premier d'errno n'est pas de détecter une erreur, mais lorsqu'une erreur a été détecter, d'en connaître la raison.

    Citation Envoyé par magicland Voir le message
    tous comme le r+ effectivement (quoique pour ce dernier il faut que le compilateur détecte direct que c'est du binaire et non du texte, d'après ce que j'ai compris c'est par défaut..)
    C'est le rôle du b (dont je n'ai pas parler dans mon message précédent). Bien sur qu'il faut garder le b, je n'ai pas dit le contraire.
    Je disais juste qu'il était inutile d'ouvrir le fichier en lecture et écriture (r+), la lecture est suffisante (r).

    Ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sp=fopen("spectacle.dat","r+b");
    peut être remplacer par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sp=fopen("spectacle.dat","rb");

  7. #7
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par magicland Voir le message
    (quoique pour ce dernier il faut que le compilateur détecte direct que c'est du binaire et non du texte, d'après ce que j'ai compris c'est par défaut..)
    alors c'est "rb"

    avec b poyr binaire


    Citation Envoyé par magicland Voir le message
    Ensuite pour le actu[1] au lieu du actu[0] je ne crois pas que c'est une incidence sur le code, j'y vois plus clair mais je perd une unité de stockage.
    oui, mais c'est juste que en C les indices vont de 0 à N-1 pour un tableau de N
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

Discussions similaires

  1. [2.x] Récupération données JSON dans un fichier TWIG
    Par Joyden dans le forum Symfony
    Réponses: 1
    Dernier message: 07/03/2015, 12h53
  2. [Débutant] Récupération de données colonnes dans un fichier .txt
    Par matlabeur dans le forum MATLAB
    Réponses: 1
    Dernier message: 25/11/2014, 14h18
  3. Réponses: 3
    Dernier message: 12/11/2009, 14h26
  4. Réponses: 5
    Dernier message: 03/07/2009, 11h55
  5. Problème de rangement de structure dans un fichier ...
    Par Freeze dans le forum C++Builder
    Réponses: 8
    Dernier message: 16/12/2003, 16h46

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