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 :

Fichier binaire structure


Sujet :

C

  1. #1
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut Fichier binaire structure
    Bonsoir ,

    J'ai un problème pour afficher les clients qui sont dans mon fichier client.dat

    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
     
    void afficher_client(client cl) {
     
        FILE *cli=NULL;
        int client;
     
        cli=fopen("client.dat","rb");
     
     
        if(cli != NULL ) {
     
            printf("N ° client : ");
            scanf("%d",&client);
            fread(&cl,sizeof(client),1,cli);
     
        while(!feof(cli)) {
     
          if(cl.cl_sj==client) {
     
            printf("Client N ° %d \n",cl.cl_sj);
            printf("Votre nom : %s ",cl.cl_nom);
            printf("Votre prenom : %s ",cl.cl_prenom);
            printf("Votre rue : %s ",cl.cl_adresse.rue);
            printf("Votre code postal : %s ",cl.cl_adresse.cp);
            printf("Votre localite : %s ",cl.cl_adresse.loc);
            printf("votre pays : %s ",cl.cl_adresse.pays);
            printf("Telephone fixe : %s ",cl.cl_tel);
            printf("Telephone portable : %s ",cl.cl_tel2);
            printf("Email : %s ",cl.cl_email);
     
                }
     
            fread(&cl,sizeof(client),1,cli);
     
            }
     
        }
     
        else {
     
            printf("Erreur d'ouverture ");
            exit(1);
     
        }
     
    }
    J'ai un fichier client.dat ou j'ai écrit plusieurs clients et je veux accéder à un client par son numéro de client mais je n'y parviens pas la console me met
    "Erreur d'ouverture " et aucun client s'affiche ?
    Pourtant le chemin est bon ? je ne vois vraiment pas ou se trouve l'erreur...

    Merci d'avance pour une aide.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Salut

    En principe, ton fichier doit se trouver dans le même répertoire que ton exécutable.

    Concernant ton code lui-même, il présente plusieurs problèmes ou incohérences :

    1) Tu extraits du fichier X octets, que tu copies à l'arrache en mémoire dans un objet de type structure. Tu t'exposes à de gros soucis, à cause des questions de boutisme, de taille des types et d'alignement des données. Cela rend le code non portable et les données extraites risquent d'avoir des valeurs bizarroïdes.
    Tu devrais plutôt sérialiser les données, en utilisant un format de type CSV, et lire/écrire les membres un par un.

    2) Oublie feof : il ne fait pas ce que tu crois, tu risques d'avoir de drôles de surprises. Pour savoir si les données ont bien été extraites (si ce n'est pas le cas, c'est qu'on a atteint la fin du fichier ou qu'il y a eu une erreur), il faut utiliser la valeur retour des fonctions de lecture : elle est faite pour ça.

    3) Problème de redondance du fread : il y en a un avant la boucle et un autre à la fin de la boucle.

    4) Les exit, c'est pas propre.

    5) Ton objet cl est local à ta fonction. Ce que tu copies dedans est détruit une fois que tu quitte la fonction.

  3. #3
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut
    Comment sérialiser les données ? et mon fichier se trouve bien dans le même répertoire que mon exécutable.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Citation Envoyé par Johnny P. Voir le message
    Comment sérialiser les données ?
    Il suffit d'écrire les données de ta structure les unes après les autres, en les séparant par un caractère délimiteur, comme (par exemple) le point-virgule. Chaque client peut être séparé par un saut de ligne.

    Pour la lecture il suffit de faire l'opération inverse. Parmi les méthodes habituelles, il y a par exemple celle-ci :
    * Pour lire la ligne courante, il y a la fonction fgets. La copie se fait vers un buffer temporaire.
    * Pour récupérer chaque donnée (token) de ce buffer, il y a la fonction strtok.
    Si la donnée courante est une chaine de caractère, il suffit d'utiliser strcpy pour la copier vers le membre de la structure correspondant.
    S'il s'agit d'un nombre (sous forme de chaine de caractères), tu peux utiliser strtol, qui permet de convertir la chaine représentant un nombre entier en un nombre entier, puis de copier ce nombre vers le membre de la structure correspondant.
    Faire ceci pour chaque donnée.
    Une fois que c'est fini, on passe à la ligne suivante, et on recommence, jusqu'à ce que le client recherché soit trouvé.

    Il y a la méthode scanf (ou ses dérivées) aussi, qui peut remplacer 10 ou 20 lignes en une seule, mais cette fonction n'est pas trop mon amie, je ne pourrai pas t'aider dessus.

    et mon fichier se trouve bien dans le même répertoire que mon exécutable.
    Je viens de remarquer que ta fonction ne referme pas le fichier qu'elle a ouvert. Ca risque de poser des soucis...

  5. #5
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut
    Je comprends tes explications , mais mon prof ne m'a jamais parlé de cela et en binaire utiliser fgets ?

    C'est bizarre , dans la fonction ajouter_client je rentre mes clients dans ma structure et j'enregistre la structure dans le fichier.
    Normalement avec ma fonction afficher_client je devrai récupérer au moins quelque chose pas qu'il m'affiche rien du tout.

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Au lieu de faire printf("Erreur d'ouverture ") fait plutôt perror("Ce que tu veux"), ça te donnera des détails sur la raison de l'erreur.

    Juste une remarque de style, interverti ton if et ton else. En général il est plus clair de traiter les cas d'erreurs immédiatement après l'instruction qui cause l'erreur, sinon quand on arrive au "else" on ne sait plus ce que l'on teste...

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Citation Envoyé par Johnny P. Voir le message
    Je comprends tes explications , mais mon prof ne m'a jamais parlé de cela et en binaire utiliser fgets ?
    C'est le prof qui vous apprend à écrire des choses du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fread(&cl,sizeof(client),1,cli);
    ? Si c'est le cas, c'est bien triste...

    Concernant fgets, il ne peut évidemment fonctionner correctement que sur des fichier texte car il remplit un buffer jusqu'à ce qu'il trouve un retour-chariot. Or, il n'y a pas de notion de retour-chariot dans des fichiers binaires.

    Si tu veux absolument remplir un objet structure à la volée, c'est ton droit, mais ce n'est absolument pas portable et c'est une source de problèmes. C'est toi qui vois.

    C'est bizarre , dans la fonction ajouter_client je rentre mes clients dans ma structure et j'enregistre la structure dans le fichier.
    Normalement avec ma fonction afficher_client je devrai récupérer au moins quelque chose pas qu'il m'affiche rien du tout.
    Je t'ai indiqué plusieurs problèmes dans mon précédent message, notamment les points 2, 3 et 5. Les as-tu corrigés ?

    Si tu veux qu'on t'aide davantage, poste un code complet et compilable. Car c'est un peu le jeu des devinettes, là.

  8. #8
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut
    J'ai fait les modifications
    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
    void afficher_client() {
     
        client cl;
        FILE *cli=NULL;
        int client;
        int	verif=false;   
     
        cli=fopen("client.dat","rb");
     
     
        if(cli != NULL ) {
     
            printf("N ° client : ");
            scanf("%d",&client);
     
       while((fread(&cl,sizeof(client),1,cli)) && verif != true ) {
     
          if(client==cl.cl_sj) {
     
            printf("Client N ° %d \n",cl.cl_sj);
            printf("Votre nom : %s \n",cl.cl_nom);
            printf("Votre prenom : %s \n",cl.cl_prenom);
            printf("Votre rue : %s \n",cl.cl_adresse.rue);
            printf("Votre code postal : %s \n",cl.cl_adresse.cp);
            printf("Votre localite : %s \n",cl.cl_adresse.loc);
            printf("votre pays : %s \n",cl.cl_adresse.pays);
            printf("Telephone fixe : %s \n",cl.cl_tel);
            printf("Telephone portable : %s \n",cl.cl_tel2);
            printf("Email : %s ",cl.cl_email);
    		verif=true;     
     
           }
     
            }
     
        }
     
        if(verif == false){
     
    		printf("Le client avec ce numero n'existe pas ");
     
         }
     
        else {
     
            perror("Erreur ");
     
        }
     
        fclose(cli);
     
    }
    Je mets aussi ma fonction ajouter_client il se peut que ça vienne de là
    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
    92
    93
    94
    95
    96
    97
    98
    99
    void ajouter_client(void) {
     
        client cl;
        cl.cl_sj=0;
        char oui='n';
        FILE *cli=NULL;
        date d;
     
        getDate(&d);
        putchar('\n');
     
        cli=fopen("client.dat","rb+");
     
        if(cli == NULL) {
     
            cli=fopen("client.dat","wb");
     
            do {  
     
                cl.cl_sj=cl.cl_sj+1;
                printf("Client N ° %d \n",cl.cl_sj);
                printf("Votre nom : ");
                scanf("%s",cl.cl_nom);
                printf("Votre prenom : ");
                scanf("%s",cl.cl_prenom);
                printf("Votre rue : ");
                scanf("%s",cl.cl_adresse.rue);
                printf("Votre code postal : ");
                scanf("%s",cl.cl_adresse.cp);
                printf("Votre localite : ");
                scanf("%s",cl.cl_adresse.loc);
                printf("votre pays : ");
                scanf("%s",cl.cl_adresse.pays);
                printf("Telephone fixe : ");
                scanf("%s",cl.cl_tel);
                printf("Telephone portable : ");
                scanf("%s",cl.cl_tel2);
                printf("Email : ");
                scanf("%s",cl.cl_email);
                fwrite(&cl,sizeof(client),1, cli);
                puts("Donnee rentree avec succes");
                getchar();
     
                do { 
                    printf("Voulez-vous entrer un nouveau client ? o/n ");
                    scanf("%c",&oui);
                }while(oui != 'n' && oui != 'o');
     
            }while(oui == 'o' || oui == 'O');
     
        }
     
     
        else {
     
            fseek(cli,0,SEEK_END); // position à la fin du fichier
            fseek(cli,-sizeof(client),SEEK_CUR); // se déplacer d'une structure en arrière à partir de la position courante
            fread(&cl,sizeof(client),1,cli); // lire la structure 
            fseek(cli,sizeof(client),SEEK_CUR);
     
            do {  
                /*incrémenter le numéro du client*/
                cl.cl_sj=cl.cl_sj+1;
                printf("Client N ° %d \n",cl.cl_sj);
                printf("Votre nom : ");
                scanf("%s",cl.cl_nom);
                printf("Votre prenom : ");
                scanf("%s",cl.cl_prenom);
                printf("Votre rue : ");
                scanf("%s",cl.cl_adresse.rue);
                printf("Votre code postal : ");
                scanf("%s",cl.cl_adresse.cp);
                printf("Votre localite : ");
                scanf("%s",cl.cl_adresse.loc);
                printf("votre pays : ");
                scanf("%s",cl.cl_adresse.pays);
                printf("Telephone fixe : ");
                scanf("%s",cl.cl_tel);
                printf("Telephone portable : ");
                scanf("%s",cl.cl_tel2);
                printf("Email : ");
                scanf("%s",cl.cl_email);
                fwrite(&cl,sizeof(client),1, cli);
                puts("Donnee rentree avec succes");
                getchar();
     
                do { 
                    printf("Voulez-vous entrer un nouveau client ? o/n ");
                    scanf("%c",&oui);
                }while(oui != 'n' && oui != 'o');
     
            }while(oui == 'o' || oui == 'O');
     
        }   
     
     
        fclose(cli);
     
    }
    Ps : pour la sérialisation des données ,
    j'ai lu que il faut déclarer statiquement les champs d'une structure pour pouvoir la sauvegarder en mode binaire (avec fwrite) sans problèmes, pas besoin de sérialisation.
    Et il se trouve que ma structure client et adresse les champs sont statique donc pas besoin de sérialiser.
    J'ai lu quelque chose de mauvais ?

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/04/2009, 20h10
  2. Réponses: 23
    Dernier message: 13/02/2009, 12h31
  3. Réponses: 9
    Dernier message: 04/06/2007, 21h44
  4. Réponses: 5
    Dernier message: 26/03/2007, 01h30

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