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 :

seekg ne recule pas


Sujet :

C++

  1. #1
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut seekg ne recule pas
    Bonjour,

    lorsque on est arrivé à la fin du fichier, seekg devrait repositionner de deux tampons en arrière et source.read devait charger le tampon précédent. Dans le débogueur, le tampon reste le même dans le tableau tampon. Pourquoi seekg ne recule pas?
    quelqu'un a une idée?

    scanneur.cpp
    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
    #include <string>
    #include <fstream>
    #include <iostream>
     
    #include "scanneur.hpp"
     
    scanneur::scanneur(std::string nomfichier):enavant(0),nbtampons(0){
      char c;
      source.open(nomfichier.c_str(),std::ifstream::binary);
      if( ! source.is_open()){
        std::cerr<<"impossible d'ouvrir "<<nomfichier<<std::endl;
        exit(1);
      }
      source.seekg(0,source.end);
      taillefichier = source.tellg();
      source.seekg (0, source.beg);
      source.read(tampon,tailletampon);
      nbtampons++;
      tampon[tailletampon]=EOF;//sentinelle
      lus=source.gcount();
      if(lus<tailletampon)
        tampon[lus]=EOF;
      for(c=carsuiv();c!=EOF;c=carsuiv())
        if(c=='\n')
          std::cout<<std::endl;
        else
          std::cout << c;
      for(int i=0;i<taillefichier;i++){
        reculer(2);
        c=carsuiv();
        if(c=='\n')
          std::cout<<std::endl;
        else
          std::cout<<c;
      }
    }
     
    char scanneur::carsuiv(){
      char c=tampon[enavant++];
      if(c==EOF){
        if(enavant==tailletampon+1){//+1 car enavant a été incrémenté
          source.read(tampon,tailletampon);
          nbtampons++;
          tampon[tailletampon]=EOF;//sentinelle
          lus=source.gcount();
          tampon[lus]=EOF;//dernier caractère du tampon chargé
          enavant=0;
          c=tampon[enavant++];
        }
      }
      return c;
    }
     
    void scanneur::reculer(int n){
      for(int i=0;i<n;i++)
        if(enavant>0)
          enavant--;
        else{
          if(nbtampons>1){
    	nbtampons-=2;
    	source.seekg(nbtampons*tailletampon,std::ios::beg);
    	nbtampons++;
    	source.read(tampon,tailletampon);
    	enavant=source.gcount();
          }
        }
    }
    scanneur.hpp
    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
    #ifndef SCANNEUR_HPP
    #define SCANNEUR_HPP
    #include <fstream>
     
    constexpr int tailletampon=7;
     
    class scanneur{
    public:
      scanneur(std::string nomfichier);
      char carsuiv();
      void reculer(int n);
    private:
      char tampon[tailletampon+1];//+1 pour la sentinelle
      int enavant,taillefichier,lus,nbtampons;
      std::ifstream source;
    };
    #endif
    main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
    #include <string>
    #include "scanneur.hpp"
     
     
    int main(int argc,char *argv[]){
      if(argc==1){
        std::cerr<<"indiquez le fichier source"<<std::endl;
        exit(2);
      }
      std::string in=argv[1];
      scanneur scan(in);
      return 0;
    }

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    j'ai changé reculer(int n):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void scanneur::reculer(int n){
      for(int i=0;i<n;i++)
        if(enavant>0)
          enavant--;
        else{
          if(nbtampons>1){
    	source.seekg((nbtampons-2)*tailletampon,std::ios::beg);
    	nbtampons--;
    	source.read(tampon,tailletampon);
    	enavant=source.gcount();
          }
        }
    }
    mais ça ne change pas d'effet.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Est-ce que tu compiles encore en C++98 ?
    Citation Envoyé par c++98
    If the eofbit flag is set before the call, the function fails (sets failbit and returns).
    Citation Envoyé par c++11
    The function clears the eofbit flag, if set before the call.
    https://cplusplus.com/reference/istream/istream/seekg/
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    Merci pour la réponse. J'ai déjà vu cette page. En utilisant l'option -std=c++11 ou -std=gnu++11 j'ai le même problème.
    Mais c'est vrai que eof est activé:
    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
    void scanneur::reculer(int n){
      for(int i=0;i<n;i++)
        if(enavant>0)
          enavant--;
        else{
          if(nbtampons>1){
    	if(source.eof())
    	  std::cout<<"\neof"<<std::endl;
    	else
    	  std::cout<<"\npas eof"<<std::endl;
    	source.seekg((nbtampons-2)*tailletampon,std::ios::beg);
    	nbtampons--;
    	source.read(tampon,tailletampon);
    	enavant=source.gcount();
          }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    123456789
     
    98
    eof
    8888888
    une idée?

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 116
    Points : 1 639
    Points
    1 639
    Par défaut
    Salut,

    Ne te fait pas chier à écrire une micro-gestion du fichier: Monte toutes les données en mémoire, fait tes opérations, et redescend tout sur le disque quand tu as terminé.
    Des structures / classes sont autrement plus simple à gérer que les données brut sur le disque.

  6. #6
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    Merci pour le hors-sujet. le fichier peut-être très volumineux. Je fais un scanneur car j'en ai besoin d'un. J'ai trouvé cette méthode dans un livre sur les compilateurs, le purple dragon book.
    voici comment j'ai résolu le problème (j'ai trouvé ça dans un de mes anciens projets):
    scanneur.hpp
    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
    #ifndef SCANNEUR_HPP
    #define SCANNEUR_HPP
     
    #include <fstream>
    #include <string>
     
    constexpr int taille=1000;
     
    class scanneur{
    public:
      scanneur(std::string const& nomFichier);
      char carsuiv();
      void reculer(int const &n);
      int getTailleFichier();
    private:
      std::ifstream fichier;
      char tampon[taille+1];// +1 car sentinelle
      int Ntampon;
      int enavant;
      int derniers;
      int tailleFichier;
    };
     
    #endif
    scanneur.cpp
    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
    #include <fstream>
    #include <iostream>
    #include "scanneur.hpp"
     
    scanneur::scanneur(std::string const& nomFichier):Ntampon(1),enavant(0),
    						  derniers(0){
      fichier.open(nomFichier.c_str(),std::ios::binary|std::ios::in);
      fichier.seekg(0,std::ios_base::end);
      tailleFichier=fichier.tellg();
      fichier.seekg(0,std::ios_base::beg);
      if(taille<=tailleFichier){
        fichier.read(tampon,taille);
        tampon[taille]=EOF;//sentinelle
      }
      else{
        derniers=tailleFichier;
        fichier.read(tampon,derniers);
        Ntampon=1;
        tampon[derniers]=EOF;//fin de fichier (pas sentinelle)
        enavant=0;
      }
    }
     
    char scanneur::carsuiv(){
      if(tampon[enavant]==EOF)
        if(enavant!=taille)
          return tampon[enavant++];//+1 car doit pointer sur le suivant
        else if((Ntampon+1)*taille<=tailleFichier){
          fichier.read(tampon,taille);
          Ntampon++;
          enavant=0;
          derniers=0;
          return tampon[enavant++];
        }
        else{
          derniers=tailleFichier%(Ntampon*taille);
          fichier.read(tampon,derniers);
          Ntampon++;
          tampon[derniers]=EOF;
          enavant=0;
          return tampon[enavant++];
        }
      else
        return tampon[enavant++];
    }
     
    void scanneur::reculer(int const &n){
      for(int i=0;i<n;i++){
        if(enavant==0){
          if(Ntampon>1){
    	fichier.seekg((Ntampon-2)*taille,std::ios_base::beg);
       	fichier.read(tampon,taille);
    	enavant=taille-1;
          }
          else if(derniers!=0)
    	enavant=derniers-1;
          else
    	enavant=taille-1;
          Ntampon--;
        }
        else
          enavant--;
      }
    }
     
    int scanneur::getTailleFichier(){
      return tailleFichier;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ ./a.out toto.txt 
    123456789
     
     
    987654321

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par deedolith Voir le message
    Des structures / classes sont autrement plus simple à gérer que les données brut sur le disque.
    c'est pour ça que je fais une classe scanneur. Je l'utilise dans le reste du programme.

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 116
    Points : 1 639
    Points
    1 639
    Par défaut
    Citation Envoyé par matser Voir le message
    Merci pour le hors-sujet. le fichier peut-être très volumineux.
    Tres volumineux ? tu peux etre plus précis ?
    Et non, ce n'est pas hors sujet.
    Citation Envoyé par matser Voir le message
    c'est pour ça que je fais une classe scanneur. Je l'utilise dans le reste du programme.
    certes, mais ta classe passe son temps à triturer un fichier.
    Charge ton fichier dans un conteneur (tableau, classe, structure, ect ...) et oublie le.

  9. #9
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    c'est pas ce qu'ils disent dans le dragonbook.

    scanneur ne lit pas directement sur le fichier, il ne lit que le tampon, lequel est rechargé quand la variable enavant arrive à la sentinelle, au bout du tampon. Le fichier est un peu "oublié" comme tu dis
    On trouve ce tampon à la ligne 17 dans scanneur.hpp
    la classe scanneur n'est utilisée seulement quand la classe lexicale demande un caractère pour trouver un lexème. Elle n'est pas tout le temps en action. Et la classe syntaxique demande de temps en temps une unité lexicale à la classe lexical.
    et si le fichier fait 1Go? dans un tableau?
    je ne triture pas un fichier, je ne fais que le lire tampon par tampon
    Je préfère écouter les grands informaticiens (A Aho, M. Lam, R. Sethi et J Ullman) qui ont écrit le purple dragon book.
    Tu l'a lu la classe scanneur? Un tampon de 1ko ne fait pas l'affaire?

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    "le dragonbook", putain c'était déjà méga vieux durant mes études, et c'était il y a plus de 30 ans.

    Les problématiques des compilateurs des années 70-80, c'était pas les mêmes que maintenant.

    >et si le fichier fait 1Go? dans un tableau?
    Rien à foutre, on n'est dans le monde du 64 bits depuis plus de 15 ans.

    >Je préfère écouter les grands informaticiens (A Aho, M. Lam, R. Sethi et J Ullman) plutôt que toi.
    Contactes les survivants sur Twiter, qu'ils rigolent.

    >Tu l'a lu la classe scanneur? Un tampon de 1ko ne fait pas l'affaire?
    Mais bien sûr, du moment qu'il rentre en entier dans une ligne du cache L2 de la CPU. (On m'informe qu'il n'y avait pas de caches sur les CPU des années 70, mais c'est ballot).

  11. #11
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    tu parles peut-être du red dragonbook.
    celui que j'ai est le purple. En fait c'est vrai qu'il n'est pas récent, il date de 2007.
    désolé pour la gêne occasionné

  12. #12
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 116
    Points : 1 639
    Points
    1 639
    Par défaut
    Citation Envoyé par matser Voir le message
    et si le fichier fait 1Go? dans un tableau?
    Avec de "Si", on refait le monde, et on met à genoux n'importe quel système informatique, même ceux qui n'ont pas encore été conçu.

    Les très gros fichiers (base de données ? système de fichier propriétaire ?) sont pris en charge par des programme autrement plus évolués que ce que tu nous présente.
    Fait quelque chose de réaliste plutôt que théorique.

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    L'édition Originale est de 1986 :
    https://en.wikipedia.org/wiki/Compil...ues,_and_Tools

    Je ne pense pas que tu t'inspires des extensions de la seconde édition.

  14. #14
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    Je ne pense pas que tu t'inspires des extensions de la seconde édition.
    quest-ce qu tu en sais? J'utilise la seconde édition depuis que je l'ai

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Citation Envoyé par matser Voir le message
    quest-ce qu tu en sais? J'utilise la seconde édition depuis que je l'ai
    - Directed translation
    - New data flow analyses
    - Parallel machines
    - Garbage collection
    - New case studies

    Laquelle de ces extensions, SVP ?

  16. #16
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    j'en suis au chapitre 5 traduction dirigée par la syntaxe

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Si les vieilleries que vous donnez dans le sujet https://www.developpez.net/forums/d2...w-char-length/ viennent de ce que vous avez lu dans ce bouquin, on a clairement la réponse sur la "fraîcheur" de l'édition de 2007.

  18. #18
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    non ce char *... vient de https://cplusplus.com/reference/istream/istream/seekg/

    j'ai posé la question parce que ça me semblait bizard

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    La vache, cet exemple des enfers, il fait mal aux yeux.
    A ne pas copier, SVP.

  20. #20
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    OK, pas de problème, je ne copie pas

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

Discussions similaires

  1. Réponses: 90
    Dernier message: 25/11/2019, 21h40
  2. Programmer encore en VB 6 c'est pas bien ? Pourquoi ?
    Par Nektanebos dans le forum Débats sur le développement - Le Best Of
    Réponses: 85
    Dernier message: 10/03/2009, 14h43
  3. Pas de fork sous Windows?
    Par chezjm dans le forum POSIX
    Réponses: 8
    Dernier message: 11/06/2002, 12h15

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