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 de traitement aléatoire EOF


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Inscrit en
    Novembre 2007
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 4
    Par défaut Problème de traitement aléatoire EOF
    Bonjour à tous
    - Pour parcourir mon fichier j'utilise
    Mes déclarations

    #define MAX_REC_LEN 2044
    char bufline[MAX_REC_LEN+2];
    FILE* curr_file;

    while ((code = read_line()) != EOF)
    {
    ...

    -La fonction read_line est la suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int read_line()
    {
    	memset(bufline,0,MAX_REC_LEN+2);
    	if (fgets(bufline, MAX_REC_LEN+2, curr_file)==NULL)
    	{
    		return EOF;
    	}
    	if (bufline[0]==0) return EOF;
    	return 1;
    }
    curr_file: Mon fichier
    bufline : est censé contenir la ligne du fichier.

    Mon problème c'est que ma fonction read_line me retourne parfois un EOF (le premier) directement, mais ce problème est aléatoire, je remets le même fichier dans le répertoire de traitement et il est traité sans problème.

    Est ce que c'est possible que ça soit un problème de mémoire ? ou c'est autre chose ?

    Merci pour votre aide

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    C'est quoi EOF?
    Ca veut dire "End Of File", mais je ne pense pas que ce soit une constante définie.
    Habituellement, on écrit cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    FILE *in=fopen("fictier","rt"); // ou autre-chose
    while (!feof(in))
    {
    ...
    //lecture
    ...
    } 
    fclose(in);
    Si vous replacez EOF par 0 (par exemple) vous y verrez déjà plus clair.

  3. #3
    Futur Membre du Club
    Inscrit en
    Novembre 2007
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 4
    Par défaut
    Oui c'est bien END OF FILE, elle est définit dans un autre fichier, mais j'ai oublié de mentionner ça.

    Ce que je n'ai pas compris, c'est que c'est un problème aléatoire, je n'ai pas toujours ce problème.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Avez regardé le bout de code que j'ai écrit et ce qu'a écrit jeroman.?

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Citation Envoyé par Pierre Dolez Voir le message
    Bonjour,
    C'est quoi EOF?
    Ca veut dire "End Of File", mais je ne pense pas que ce soit une constante définie.
    ....
    Si vous replacez EOF par 0 (par exemple) vous y verrez déjà plus clair.
    EOF est une constante définie comme étant un int de valeur négative. Elle est définie dans <stdio.h>

  6. #6
    Invité
    Invité(e)
    Par défaut
    Exact, pardon.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define EOF (-1)                /* End of file indicator */

  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
    Je soupçonne l'utilisation de globales (car ta fonction de lecture n'a aucun argument), c'est pas propre et source de bugs (on peut modifier la valeur n'importe où dans le code).

    Ce code (une ébauche), qui sert d'exemple, fonctionne chez moi. A adapter.
    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
    #include <stdio.h>
     
    #define MAX_REC_LEN 2044
     
    int read_line(char * bufline , int taille , FILE * curr_file)
    {
        if ( fgets(bufline , taille , curr_file) == NULL )
        {
            return EOF;
        }
     
        /* A FAIRE : rechercher '\n' ou "\r\n" et remplacer par '\0' */
     
        if (bufline[0] == 0)
            return EOF;
     
        return 1;
    }
     
    int main(void)
    {
        int code;
        int numero_ligne = 0;
        char bufline[MAX_REC_LEN+2];
        FILE* curr_file;
     
        if ((curr_file = fopen("Fichier.txt","rb")) == NULL)
            return 0;
     
        while ( (code = read_line(bufline , MAX_REC_LEN+2 , curr_file)) != EOF )
        {
            numero_ligne++;
            printf( "ligne %d : %s" , numero_ligne , bufline );
        }
     
        return 0;
    }
    J'ai viré le memset, qui ne sert à rien. Il y a des choses à rajouter (voir commentaire).

    Je ne comprend pas pourquoi créer un tableau de dimension REC_LEN+2. Pourquoi +2 ? Et pourquoi précisément 2044 ? J'ai laissé tel quel, mais je trouve ça bizarre.

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Sixclopes Voir le message
    Est ce que c'est possible que ça soit un problème de mémoire ?
    Le problème ne vient pas de ce qui est montré, même si le code n'est pas d'un style particulièrement à conseiller.

    Citation Envoyé par Pierre Dolez Voir le message
    Habituellement, on écrit cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    FILE *in=fopen("fictier","rt"); // ou autre-chose
    while (!feof(in))
    {
    ...
    //lecture
    ...
    } 
    fclose(in);
    J'espère bien que non. Habituellement l'utilisation de feof pour contrôler une boucle dénote plutôt une mauvaise compréhension du comportement des IO en C. Si le code de l'OP est stylistiquement pas à conseiller, une telle utilisation de feof est généralement erronée.

    La boucle de lecture par ligne canonique en C est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    while (!fgets()) {
       /* vérification de tampon trop court */
       /* utilisation */
    }
    if (ferror(...)) {
       /* erreur d'IO */
    } else {
       /* fin de fichier */
    }

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Habituellement l'utilisation de feof pour contrôler une boucle dénote plutôt une mauvaise compréhension du comportement des IO en C. Si le code de l'OP est stylistiquement pas à conseiller, une telle utilisation de feof est généralement erronée.
    Il serait intéressant de préciser une utilisation de feof() "à conseiller".
    Dans votre exemple, vous faites une lecture du fichier avec fgets(). En réalité, et dans le cas général, la lecture peut être faite avec plusieurs fonctions, et un bonne gestion prévoira la présence d'une donnée marquent la fin du fichier, de façon à sortir de la bouche while.
    En quelque-sorte, l'instruction !feof(in) est là par sécurité et dans la pratique, un programme doit prévoir cette instruction et les instructions de lecture seront à l'intérieur de la boucle.
    D'ailleurs, à titre personnel, je n'utilise fgets() que dans les cas où je suis sûr de l'organisation en lignes, par exemple un fichier CSV. C'est à dire que j'utilise fgetc(), naturellement par l'intermédiaire d'une fonction de lecture.
    Dernière modification par Invité ; 25/09/2010 à 12h53.

  10. #10
    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 : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Pierre Dolez Voir le message
    Dans votre exemple, vous faites une lecture du fichier avec fgets(). En réalité, et dans le cas général, la lecture peut être faite avec plusieurs fonctions
    Ce qui ne change pas fondamentalement les choses, toutes les fonctions de lecture ont un mécanisme similaire permettant d'indiquer qu'une erreur ou que la fin de fichier a été rencontré. Il suffit d'utiliser le test correspondant à la fonction de lecture utilisée.

    Citation Envoyé par Pierre Dolez Voir le message
    En quelque-sorte, l'instruction !feof(in) est là par sécurité et dans la pratique, un programme doit prévoir cette instruction et les instructions de lecture seront à l'intérieur de la boucle.
    Le problème c'est que simplement boucler sur feof() ne fonctionne pas. Il faut bel et bien tester le retour des fonctions de lecture. feof() permet simplement, si c'est nécessaire, de distinguer la fin de fichier d'une autre erreur de lecture.

  11. #11
    Invité
    Invité(e)
    Par défaut
    OK,
    Mais je ne sais toujours pas quand la fonction feof() peut être utilisée correctement.

  12. #12
    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
    Comment ta fonction connait le pointeur sur le fichier si tu ne lui passes pas en argument ? Même chose pour bufline... Ce sont des globales ?

    Dans l'ordre :
    Il faut ouvrir le fichier.
    Vérifier s'il est bien ouvert.
    Si tout est bon : ensuite, tu peux lire chaque ligne via ta fonction en lui passant le pointeur sur le fichier et l'adresse où écrire la ligne (bufline), en argument.

    Je ne comprends pas l'utilité du memset. S'il s'agit d'un fichier texte, la ligne est censée se terminer par un '\n' (qui pourra être supprimé par la suite en le remplaçant par un '\0'). Et s'il n'y en a pas, c'est que le buffer est trop petit. Remplir toute la ligne avec le caractère '\0' avant chaque lecture consomme des ressources inutilement.

  13. #13
    Futur Membre du Club
    Inscrit en
    Novembre 2007
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 4
    Par défaut
    Citation Envoyé par jeroman Voir le message
    Comment ta fonction connait le pointeur sur le fichier si tu ne lui passes pas en argument ? Même chose pour bufline... Ce sont des globales ?

    Dans l'ordre :
    Il faut ouvrir le fichier.
    Vérifier s'il est bien ouvert.
    Si tout est bon : ensuite, tu peux lire chaque ligne via ta fonction en lui passant le pointeur sur le fichier et l'adresse où écrire la ligne (bufline), en argument.

    Je ne comprends pas l'utilité du memset. S'il s'agit d'un fichier texte, la ligne est censée se terminer par un '\n' (qui pourra être supprimé par la suite en le remplaçant par un '\0'). Et s'il n'y en a pas, c'est que le buffer est trop petit. Remplir toute la ligne avec le caractère '\0' avant chaque lecture consomme des ressources inutilement.
    salut,
    C'est ce que je fais.
    j'ouvre le fichier
    if ((curr_file = fopen(filename,"r")) == NULL) return 0

    sinon la ligne se termine par un 0D 0A (Hex)
    un exemple de mon fichier en pièce jointe.

    Désolé si je l'ai répété, mais je ne comprends pas pourquoi la problème est aléatoire.

    Pierre Dolez
    Oui je viens de voir, merci, je vais essayer de modifier mon code. mais j'ai toujours utilisé cette fonction et je n'avais jamais eu un tel problème avant.

    Merci
    Fichiers attachés Fichiers attachés

  14. #14
    Invité
    Invité(e)
    Par défaut
    Votre fichier contient une seule ligne très longue.
    Il faut le lire autrement.

Discussions similaires

  1. Problème d'exécution aléatoire et inconnu
    Par en_gel_ho dans le forum Access
    Réponses: 2
    Dernier message: 15/12/2006, 12h57
  2. [DOM] Problème de traitement récursif, nombre de noeuds fils
    Par erivoil dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 13/12/2006, 12h39
  3. Problème de traitement d'image tiff
    Par Galkir dans le forum C++Builder
    Réponses: 2
    Dernier message: 29/06/2006, 09h05
  4. Problème de traitement de file
    Par Bouguennec dans le forum Langage
    Réponses: 3
    Dernier message: 09/05/2006, 17h57
  5. Problème avec traitement de chaînes
    Par cortex007 dans le forum Langage
    Réponses: 6
    Dernier message: 25/04/2006, 16h22

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