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 :

fread, buffer de lecture, feof(fichier)


Sujet :

C

  1. #1
    Membre confirmé Avatar de nicodn02
    Profil pro
    Consultant .NET
    Inscrit en
    Mars 2007
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Consultant .NET

    Informations forums :
    Inscription : Mars 2007
    Messages : 263
    Par défaut fread, buffer de lecture, feof(fichier)
    Bonjour, je vous explique mon problème.

    J'aimerai lire un fichier avec fread (car le fichier pourra être binaire, ou du texte) et stocker ma ligne lu dans un buffer pour pouvoir la traiter
    en gros, mon code ce presente comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int main(){
    /* ouverture fichier */
    ...
     
    while( !feof(fichier) ){
        lire_mot(fichier);
    }
    ...
    return 1;
    }
    et ma fonction pour lire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void lire_mot(FILE* stream){
    /* si on doit lire j'appel fread */
    if( fread(&buffer[0], ...) != -1 )
    ...
     /* et la je recupere un mot dans mon buffer*/
    ...
    }

    et en faite mon problème est que, je vais lire correctement mon fichier:
    je rappel fread que quand j'ai terminer d'extraire tout les mots
    or, qd fread va lire les derniers mots de mon fichier, je vais me trouver à la fin, et donc ma boucle !feof(fichier) me fera arreter, et donc j'aurais pas terminer "d'examiner" mon buffer de lecture.
    Comment faire?

    Merci d'avance

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Peut être quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main()
    {
       while(lire_mot() == true)
       {
          // traitement du mot lu
       }
    }
    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
     
    bool lire_mot()
    {
       // si buffer reception pas vide, traitement du buffer de récéption
       return true;
     
       // si on arrive ici, c'est que le buffer de reception est vide ou bien pas assez complet
     
       // si fichier pas ouvert, ouvrir fichier
     
       // si on doit lire j'appel fread
       if(fread(buffer_reception, ...) == -1)
       {
          // erreur de lecture, c'est probablement la fin du fichier
          // fermeture du fichier
          return false;
       }
     
       // traitement du buffer de reception
       return true;
    }
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    L'algo pour la lecture c'est (il y a d'autres méthodes ...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fread;
    while not feof
        fread;
    feof ne retourne "vrai " que si on a tenté de lire alors qu'on est déjà à la fin du fichier, pas après avoir lu le dernier octet.

  4. #4
    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
    Sauf qu'à ma connaissance, le résultat de feof() n'est pas défini tant que fread() n'a pas retourné une erreur. Melem, Emmanuel va te taper sur les doigts...
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while fread
    	traiter buffer
     
    # fini : Erreur ou fin de fichier ?
    if feof
    	#fin du fichier
    else
    	#erreur
    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.

  5. #5
    Membre confirmé Avatar de nicodn02
    Profil pro
    Consultant .NET
    Inscrit en
    Mars 2007
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Consultant .NET

    Informations forums :
    Inscription : Mars 2007
    Messages : 263
    Par défaut
    merci,

    je voyais aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    while(!feof(fichier)){
      lire_mot;
      ...
    }
    /* on sort car fin du fichier est dans le buffer */
    /* je verifie si mon buffer a été traité grace a un marqueur position lecture, si il est retourne a 0 ou si il a depacé la taille du buffer */
    while( !vide ){
     /* je traite la fin du buff */
    }
    quand pensez-vous?


    j'avais aussi pensez à, comme j'ai un marqueur d'où je dois commencer a lire mon buffer, et que je connais la taille du buffer, faire en sorte que cela m'arrete ma boucle while, mais je n'y arrive pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while( !feof(fichier) || positionLecture !=-1 ){
    lire_mot();
    ...
    }
    cependant, dans lire_mot, je ne vois pas quand mettre ce positionLecture a -1, trouver le bon moment

  6. #6
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par Médinoc
    Sauf qu'à ma connaissance, le résultat de feof() n'est pas défini tant que fread() n'a pas retourné une erreur
    En effet. Mais une tentative de lecture à la fin d'un fichier provoque une erreur. Seulement, je n'ai peut-être pas été assez précis dans l'exemple car en fait c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    fread;
    while not feof
    {
        traitement; /* <-- j'ai oublie de mettre ceci */
        fread;
    }

  7. #7
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Il se passe quoi si il y a une erreur de lecture ?

  8. #8
    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 Melem Voir le message
    En effet. Mais une tentative de lecture à la fin d'un fichier provoque une erreur. Seulement, je n'ai peut-être pas été assez précis dans l'exemple car en fait c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    fread;
    while not feof
    {
        traitement; /* <-- j'ai oublie de mettre ceci */
        fread;
    }
    Avec ce code, si le programme rencontre une erreur quelconque avant la fin du fichier, tu vas partir dans une boucle infinie.
    Il faut egalement utiliser ferror() ou verifier la valeur de retour de fread().

    Personellement, je prefere tester la valeur de retour de la fonction puis, si il est necessaire de differencier la fin de fichier d'une autre erreur, d'utiliser feof() et ferror() pour determiner ce qui 'est produit.

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Melem Voir le message
    En effet. Mais une tentative de lecture à la fin d'un fichier provoque une erreur. Seulement, je n'ai peut-être pas été assez précis dans l'exemple car en fait c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    fread;
    while not feof
    {
        traitement; /* <-- j'ai oublie de mettre ceci */
        fread;
    }
    Tu as des fonctions de lecture qui te sont offertes et qui ont aussi pour but de vérifier si le fichier a été lu et tu viens nous demander notre avis sur tes exemples crado !!! Ben t'as la réponse => Ton exemple est crado (et heureusement que Emmanuel n'est pas passé par 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
    while fread() > 0
    {
        traitement;
    }
     
    // Eventuellement
    if feof()
    {
         // Fin de fichier
    }
    else
    {
         // Erreur de lecture
    }
    Citation Envoyé par gl Voir le message
    Personellement, je prefere tester la valeur de retour de la fonction puis, si il est necessaire de differencier la fin de fichier d'une autre erreur, d'utiliser feof() et ferror() pour determiner ce qui 'est produit.
    Exactement ! Un comportement normal qui mène à un code simple et sain !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par dapounet Voir le message
    Il se passe quoi si il y a une erreur de lecture ?
    Si cette erreur est due à une tentative de lecture à la fin d'un fichier, feof retourne VRAI.
    Citation Envoyé par gl
    Avec ce code, si le programme rencontre une erreur quelconque avant la fin du fichier, tu vas partir dans une boucle infinie.
    Exact, c'est ça le vrai problème. D'ailleurs les techniques de lecture intégrale à base de feof ne sont pas très recommandées (parce que ça complique inutilement le programme, alors qu'il y a d'autres techniques plus simples). Avec fread, il vaut mieux tester le nombre d'octets effectivement lus. Avec getc/fgetc, il vaut mieux tester EOF. Et c'est plus simple comme ça.

  11. #11
    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 Melem Voir le message
    Exact, c'est ça le vrai problème.
    Je vois au moins deux autres "problèmes" (enfin problème est un bien grand mot, il s'agit plus d'une question de goût) avec une boucle de lecture utilisant feof() comme condition de sortie:

    * L'ordre nature d'une itération est LECTURE - TEST - UTILISATION, ce qui oblige, comme dans l'exemple que tu as fourni a effectuer deux appels a la fonction de lecture (un avant la boucle et un en fin d'itération) ce qui complique inutilement le code.
    * Par souci de symétrie : en C, généralement, on teste la valeur de retour pour connaitre le résultat de l'exécution de la fonction quitte éventuellement a utiliser ensuite un autre mécanisme pour affiner ce résultat (utilisation de fonction type feof(), lecture de errno, etc.), je ne vois pas de raison de ne pas appliquer ce schéma à la lecture de fichier.
    D'autant plus qu'il est probable que le retour de la fonction soit déjà utilisé dans le traitement (récupération du caractère pour fgetc(), nombre de caractères lus pour fread(), nombre de conversions réussies pour fscanf(), etc.), on se retrouve alors à utiliser deux mécanismes différents là où un seul pourrait suffire.

  12. #12
    Membre confirmé Avatar de nicodn02
    Profil pro
    Consultant .NET
    Inscrit en
    Mars 2007
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Consultant .NET

    Informations forums :
    Inscription : Mars 2007
    Messages : 263
    Par défaut
    Bonjour,

    ok pour tous cela mais ma fonction appelant fread se trouve à part de ma boucle while

    ma fonction lire_mot me retourne 1 (la fonction s'est bien déroulée, autrement dit, fread + allocation memoire pour le mot), et 0 dans le cas contraire.

    cependant, je ne fais pas appelle à fread à chaque fois que je rentre dans cette fonction. En effet:
    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
     
    int lire_mot(..., char **mot){
        ...
     
        if( m->posLecture < 0 || m->posLecture >= m->tailleBuffer ){
            memset(&(m->buffer[0]), '\0', m->tailleBuffer);
            tmp = fread(&(m->buffer[0]), sizeof(char), m->tailleBuffer-1, m->fichier);
     
            if( tmp == -1 )
                return 0;
     
    		m->buffer[m->tailleBuffer-1]='\0';
     
            m->posLecture = 0;
        }
     
     
        tmp = m->posLecture;
     
        ... /* recherche du mot par une boucle while + on place un \0 a la fin du mot */
     
     
    	*mot = (char*)malloc(sizeof(char)*(strlen(&(m->buffer[tmp]))+1));
        strcpy(*mot, &(m->buffer[tmp]));
     
        m->posLecture++;
     
        return 1;
    }
    voila en gros le squellette de la fonction lire_mot.
    Je ne fais appelle à fread que si j'ai traiter entierement mon buffer.
    si j'utilise feof(fichier) dans ma boucle while de la fonction appelante, quand je vais casser cette boucle, mon buffer ne sera pas entierement traiter.

    Comment faire?

    Merci

  13. #13
    Inactif  
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2003
    Messages : 570
    Par défaut
    grand merci !
    votre post m'a aidé à résoudre une segmetation fault que je n'aurais jamais pu voir

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par nsanabi Voir le message
    grand merci !
    votre post m'a aidé à résoudre une segmetation fault que je n'aurais jamais pu voir
    Remonter un topic d'il y a 2 ans... ben au-moins ça montre que t'as pris la peine de chercher sur le forum !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Inactif  
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2003
    Messages : 570
    Par défaut
    je savais que le topic est ancien mais j'ai ressenti le devoir de dire merci
    et pour la recherche j'avoue que grace à elle j'ai trouvé réponse à la majorité de mes problèmes sans poster de question

Discussions similaires

  1. Lecture rapide fichier binaire & Buffer
    Par Eames38 dans le forum C++
    Réponses: 6
    Dernier message: 15/06/2011, 16h39
  2. Réponses: 4
    Dernier message: 05/04/2011, 15h15
  3. [fread] Lecture de fichier binaire
    Par christophe_halgand dans le forum MATLAB
    Réponses: 16
    Dernier message: 03/11/2008, 18h17
  4. Lecture de fichier avec fread.Taille limitée?
    Par cheveche4 dans le forum C
    Réponses: 5
    Dernier message: 15/06/2007, 14h56
  5. [fread] Problème de lecture de buffer
    Par karl3i dans le forum C
    Réponses: 2
    Dernier message: 25/09/2003, 09h21

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