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 :

fgets, comment déterminer une erreur de lecture


Sujet :

C

  1. #1
    kap
    kap est déconnecté
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 188
    Points : 72
    Points
    72
    Par défaut fgets, comment déterminer une erreur de lecture
    Bonjour à tous,
    Je dois récupérer des données dans un fichier. J'ouvre celui-ci en mode binaire et j'utilise ensuite fgets.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(fgets(ligne, sizeof ligne, fIn)!=NULL)
    Mais fgets ne parcourt pas toutes les lignes de mon fichier. J'ai donc testé à la fin de mon programme si la fin de fichier avait été rencontré par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(feof(fOut)) fprintf(fOut,"fin de fichier rencontré");
    else fprintf(fOut,"erreur");
    et cela me renvoie "erreur". J'en ai donc déduis que fgets rencontrait une erreur mais comment puis-je déterminer cette erreur de lecture et y remédier?

  2. #2
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Bonjour et bienvenue sur le forum
    la réponse se trouve dans les pages man :
    The function fgets() may also fail and set errno for any of the errors specified for the routines

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Heu je crois que pour lire dans un fichier binaire il faut utiliser fread ... il me semble bien que les fichiers binaires sont toujours formattés d'une manière bien spécifique !
    Si tu dis que tu as testé ton fgets avec un feof à la fin de ton programme ... hum hum, normalement ca se test directement dans la boucle while, directement au début apres le fgets !

  4. #4
    kap
    kap est déconnecté
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 188
    Points : 72
    Points
    72
    Par défaut
    je ne sais pas si je l'ai bien utilisé mais errno me renvoie 0 donc à priori il n'y a pas d'erreur
    je ne comprends pas alors que le fgets ne s'effectue pas jusqu'au bout puisque la fin de fichier n'est pas rencontré non plus

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    On peut voir ton code ?

  6. #6
    kap
    kap est déconnecté
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 188
    Points : 72
    Points
    72
    Par défaut
    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
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
     
    int main(void)
    {
     
    char ligne[3000];
    FILE* fIn; 
    FILE* fOut;
    int position,j,type_ligne;
    extern int errno; 
     
    if((fIn= fopen("YTOPTIC.D", "rb")) == NULL) // ouverture du fichier source
             {
             printf("erreur, mauvais fichier source rentré");      
             system("pause"); 
             return (1);
             }  
     
    if((fOut = fopen("optic.tmp", "w")) == NULL) //ouverture du fichier destination
             {
             printf("erreur, mauvais fichier destination entré");      
             fclose(fIn);
             return (1);
             }
     
    while(fgets(ligne, sizeof ligne, fIn)!=NULL) 
              {type_ligne=0;
     
     
              if(((int)ligne[4]==49 && (int)ligne[5]==57 )|| ((int)ligne[4]==50 && (int)ligne[4]==48))
                {
                type_ligne=1;
                }
     
               switch(type_ligne)
     
                     {case 1:                                                                                  
                      for(j=0;j<90;j++)
                      {
                      putc(ligne[position],fOut);
                      if (j==77 /*|| j==18 || j==33 || j==37*/)fprintf(fOut,";");
                      position++;
                      }
                      fprintf(fOut,";");                                                                                           fprintf(fOut,"%d",errno); 
                      fprintf(fOut,"\n");
                      break;
     
                      }
              }
     
    if(feof(fOut)) fprintf(fOut,"fin de fichier rencontré");
    else fprintf(fOut,"erreur");       
    }
    j'ai enlevé à l'intérieur du case plein de petites boucles du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(position=0;position<10;position++)
                      {
                      putc(ligne[position],fOut);
                      }
    j'espères que c'est clair

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    C'est ce que je pensais au niveau de l'erreur de codage. Ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if(feof(fOut))
    {
       fprintf(fOut,"fin de fichier rencontré");
       ...
       /* On sort de la boucle */
       break;
    }
    devrait être dans ta boucle While et meme mieux, cela doit etre ta premiere instruction dans la boucle ... endehors de la boucle, ca ne sert pas a grand chose !

    Et ta boucle un peu modifiée en consequence:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(fgets(ligne, sizeof ligne, fIn))

  8. #8
    kap
    kap est déconnecté
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 188
    Points : 72
    Points
    72
    Par défaut
    Voila j'ai essayé ta solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(fgets(ligne, sizeof ligne, fIn)!=NULL) 
              {
              if(feof(fOut)) fprintf(fOut,"fin de fichier rencontré");
              else fprintf(fOut,"erreur\n");
    mais ça m'affiche toujours "erreur" donc la fin de fichier n'est jamais recontrée

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 47
    Points : 46
    Points
    46
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
               if(((int)ligne[4]==49 && (int)ligne[5]==57 )|| ((int)ligne[4]==50 && (int)ligne[4]==48))
    je suppose que le dernier, tu voulais dire ligne[5]

    d'autre part, fgets lit des chaînes sur un flux, c'est une opération formatée. Je ne l'ai jamais essayé sur un flux binaire, mais je suis dubitatif. moi j'utiliserais fread.

    enfin l'utilisation de la macro putc au lieu de la fonction fputc te fait certes gagner un peu de temps d'exécution, mais tu prends le risque des effets de bord.

  10. #10
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par kap
    Voila j'ai essayé ta solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(fgets(ligne, sizeof ligne, fIn)!=NULL) 
              {
              if(feof(fOut)) fprintf(fOut,"fin de fichier rencontré");
              else fprintf(fOut,"erreur\n");
    mais ça m'affiche toujours "erreur" donc la fin de fichier n'est jamais recontrée
    Deja pour lire un fichier binaire le mieux et le plus approprié est de lire avec fread car comme dit plus haut, un fichier binaire dans la plupart des cas est un fichier formatté de façon bien spécifique, donc tu doit récupérer les données de la même maniere qu'à l'écriture !

    Exemple de boucle de lecture:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    while (1)
    {
       int nblocs = fread (&ta_struct_ou_varaible_etc, sizeof (ta_struct_ou_varaible_etc), fIn);
     
    /* ensuite tu peut tester la fin du fichier */
    if (feof (entree)) break;
     
    /* on peut aussi tester la variable nblocs */
    if (nblocs != 1) break; /* Erreur de lecture */
    ...
    }

  11. #11
    kap
    kap est déconnecté
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 188
    Points : 72
    Points
    72
    Par défaut
    j'utilise fgets parceque je dois traiter les lignes de mon fichier différemment et je ne dois pas récupérer toutes les données, seulement celles qui m'intéressent ou en tout cas qui ont un sens à mes yeux. J'ouvre le fichier en binaire parceque le fichier en question contient notament des prix codés en héxadécimal : 021A25 pour 21.25 euros et donc le caractère de fin de fichier apparait avant la fin de fichier. Je vois pas trop comment utiliser fread parceque si je mets le resultat dans un tableau de caractère ca va être galère pour remmettre tout ça en forme afin de l'exporter sous excel...

  12. #12
    kap
    kap est déconnecté
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 188
    Points : 72
    Points
    72
    Par défaut
    euh bon en fait artatum avait vu juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(((int)ligne[4]==49 && (int)ligne[5]==57 )|| ((int)ligne[4]==50 && (int)ligne[4]==48))
    je suppose que le dernier, tu voulais dire ligne[5]
    ça change un peu tout désolé de vous avoir fait perdre votre temps avec une erreur à la c..
    par contre ça m'intéresserait de savoir comment vous vous y prendriez avec fread pour traiter mon problème

  13. #13
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par kap
    euh bon en fait artatum avait vu juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(((int)ligne[4]==49 && (int)ligne[5]==57 )|| ((int)ligne[4]==50 && (int)ligne[4]==48))
    je suppose que le dernier, tu voulais dire ligne[5]
    ça change un peu tout désolé de vous avoir fait perdre votre temps avec une erreur à la c..
    par contre ça m'intéresserait de savoir comment vous vous y prendriez avec fread pour traiter mon problème
    Pour utiliser fread, il faut deja savoir comment sont enregistrer les données dans le fichier car, dans le cas où les données se trouvaient dans un structure, il faudrais au mieux que tu lise les données et les ajoutent (par le biais de la condition de la boucle) dans une structure identique et biensur dans le meme ordre !

  14. #14
    kap
    kap est déconnecté
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 188
    Points : 72
    Points
    72
    Par défaut
    il faut deja savoir comment sont enregistrer les données
    Ca je sais pas trop car je recupère des données de clients qui étaient chez un concurrent pour les injecter dans notre logiciel.
    Si tu veux encore y consacrer du temps je peux t'envoyer le fichier mais dans la mesure où mon erreur a été trouvé on peut aussi s'arréter là.

    Merci à tous pour votre aide

  15. #15
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par CSoldier
    C'est ce que je pensais au niveau de l'erreur de codage. Ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if(feof(fOut))
    {
       fprintf(fOut,"fin de fichier rencontré");
       ...
       /* On sort de la boucle */
       break;
    }
    devrait être dans ta boucle While et meme mieux, cela doit etre ta premiere instruction dans la boucle ... endehors de la boucle, ca ne sert pas a grand chose !

    Et ta boucle un peu modifiée en consequence:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(fgets(ligne, sizeof ligne, fIn))
    bah non, il était très bien où il était : on boucle tant qu'une erreur ou la fin du fichier n'est pas apparue. Il fois que fgets nous renvoi NULL, on sort de la boucle et c'est là que l'on va tester la cause de la sortie de la boucle (grâce à feof ou ferror). Si c'est une erreur, errno pour en savoir plus.

    @CSoldier : avec ton code, si on a une erreur, on ne sortira jamais de la boucle.

    @kap : n'oublie pas le fclose à la fin.

  16. #16
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Bah moi en generale je fait tous les tests possibles dans la boucle directement, si une erreur, un ptit break; et on sort !

  17. #17
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    désolé, si tu sors de la boucle puisque fgets renvoi NULL mais avec une boucle while, le ne seras pas exécuté une fois que fgets aura retourné NULL (puisque la boucle sera fini) donc tu perd du temps lorsque que tu ais en phase de lecture et une fois que le test devient utile, tu ne t'en sert pas

  18. #18
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    J'avais pas vu les choses sous cet angle, en effet

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par CSoldier
    Heu je crois que pour lire dans un fichier binaire il faut utiliser fread ... il me semble bien que les fichiers binaires sont toujours formattés d'une manière bien spécifique !
    Un fichier n'est ni binaire ni texte. C'est une suite d'octets, c'est tout.

    Simplement, la façon de l"ouvrir (texte, binaire) influence la façon d'interpréter les fins de lignes. En mode binaire, une fin de ligne est exactement le caractère '\n' (code 10 en ASCII). En mode texte, ça dépend du système.

    Unixoide : '\n'
    Mac OS (sauf X) : '\r'
    DOS-Windows : '\n\r'
    etc.

    Mais le langage C fournit l'abstraction qui fait que, vue du programmeur, une fin de ligne est toujours '\n' lorsque le fichier est ouvert en mode texte.

    D'autre part, le fait que le fichier soit organisé en lignes et qu'il ne comporte que des caractères imprimables est lié à la volonté de celui qui a écrit dedans et non à son mode d'ouverture. La seule chose est que lorsqu'on écrit ' \n' dans un fichier ouvert en mode texte, la séquence produite peut changer d'un système à l'autre.

    Ceci dit, tu as raison de dire que fgets() n'est certainement pas la meilleure des fonctions pour lire du binaire.

    Tout ceci pour dire qu'il ne faut pas confondre 'organisation des données dans un fichier' et 'mode d'ouverture', même si il est préférable de les faire coïncider.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 25/08/2006, 14h15
  2. [Oracle 10g] Comment résoudre une erreur ORA-3000
    Par DoRiane dans le forum Oracle
    Réponses: 3
    Dernier message: 10/04/2006, 09h44
  3. comment intercepté une erreur
    Par Guillau.laurent dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 30/03/2006, 09h28
  4. Comment détecter une erreur dans un process
    Par chuckboy dans le forum MFC
    Réponses: 3
    Dernier message: 25/10/2005, 10h40
  5. Comment lancer une erreur dans une procédure stockée
    Par borgfabr dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 17/05/2005, 17h06

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