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 :

indicer les lignes d'un fichier texte


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut indicer les lignes d'un fichier texte
    Bonjour,

    Je dois manipuler les lignes d'un fichier texte, et je voudrais savoir s'il existait une commande permettant d'indicer les lignes d'un fichier texte.
    C'est-à-dire d'avoir au final la possibilité de sélectionner la ligne 'i', par exemple ligne[i] .

    Merci beaucoup !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Tu es dans le forum C++.

    Un fichier texte est composé de lignes qui sont délimitées par des CR ou de LF qui devront être lues avant de pouvoir être traitées par le programme.

    Il y a bien des façons de lire ce type de fichier:
    • ligne par ligne sans les mémoriser, il suffit de compter le nombre de lectures pour savoir quelle est la ligne courante,
    • ligne par ligne en mémorisant les lignes lues dans un tableau. Ca prend de la place en mémoire, mais l'indice du tableau donnera le numéro de ligne.
    • en "mappant" le fichier en mémoire. Dans ce cas, il faudra trouver les fin de ligne et les mettre dans un tableau.


    Pour l'instant, il serait bon de préciser ce que vous envisagez de faire.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    un std::vcetor<std::string> couplé à cette entré de la FAQ te permet de faire ce que tu souhaite.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut
    bonjour,

    Alors en fait j'ai un fichier qui se structure de la sorte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ------entre 3 et 4 lignes qui m'interessent pas ---
    ------------------------------------------------
    ------------------------------------------------
    ------------------------------------------------
    <name>name1</name>
    <coordinates> long1,latt1</coordinates> 
    <name>name2</name>
    <coordinates> long2,latt2</coordinates> 
    <name>name3</name>
    <coordinates> long,latt3</coordinates> 
    etc...
    Et je veux supprimer ces lignes inutiles.

    Voici mon problème, je manipule des fichiers qui n'auront pas forcement le meme nombre de lignes inutiles, donc il me faut un programme qui supprime ces lignes quelque soit le fichier.
    Pour cela j'ai pensé jouer les caractères reconnaisables des lignes, ie :
    je prend la ligne[i], si à la ligne[i+1] il n'y a pas le string <coordinates> j'efface la ligne i .
    Ca m'assurerait d'effacer les 4 1eres lignes car il n'y pas de <coordinate> dedans, et cela pour n'importe quel fichier que j'utilise...


    Il est fortement possible que je me complique la tâche, mais je ne vois que cela pour le moment...

    Si vous avez une meilleur (ou moins pire) idée je suis totalement preneur et je serai reconnaissant à vie !

    mercii

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Vous avez déjà fait un post: http://www.developpez.net/forums/sho...70#post3480899
    à ce sujet.

    Il vous avait été suggéré de parser le fichier avec une librarie XML. Ce qui me semble raisonnable. Qu'est ce qui ne vous plait pas avec cette suggestion?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut
    Le problème est que je ne connais absolument pas le XML, comment cela fonctionne etc. je le ferai si c'est mon dernier recours, mais il me reste que peu de temps pour mon porjet et apprendre le XML peut me prendre pas mal de temps...et je ne sais pas combien il pourrait m'en faire gagner...

  7. #7
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Tu ne connais pas XML alors que la structure que tu donne est (quasiment) de l'XML ?
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  8. #8
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut
    oui mais c'est pas moi qui l'ai fait , c'est seulement un fichier que je récupère, et sur lequel je dois bosser... l'apprentissage de xml est dur? enfin il faut y passer 1-2 journées ou en quelques exemples je peux avoir les bases? y-a-t'il un tutorial débutant, disant déjà si il faut télécharger quelque chose (j'utilise visual C++) , et que faut-il ouvrir en début de programme etc. ??

  9. #9
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Voici un document pour gérer les fichiers XML en C++.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    D'après ce que j'en ai compris, vous souhaitez "filtrer" dans votre fichier XML les contenus délimités par les balises "name" et "coordinates".
    ie ne garder que les lignes de la forme:
    • <name> sfskjdkqjs </name>
    • <coordinates> lksjdlkjsd </coordinates>

    Considérez votre fichier comme un flux et commencez par ne garder que le contenu de lignes de la forme:
    • { sfskjdkqjs }
    • [ lksjdlkjsd ]

    Puis vous modifiez le code précédent pour traiter les balises et non {}[]:
    • détecter '<'
    • déterminer s'il s'agit une balise de fin '/'
    • récupérer le 'token'
    • ....

    Je trouve cela assez bourrin.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut
    Bonjour,

    Alors j'ai effectué le code suivant :
    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
     
    int main(int argc, char* argv[])
    {
                vector<string> vect(50); //je crée mon vecteur
    	int i;                   
    	ifstream ifs( "new_toto2.txt" );
    	ofstream ofs( "vecteur.txt" );
    	string line;	
     
    //-------------------------CREATION DU VECTEUR-------------------------             for(i=0;i<vect.size();++i)
    	{	
    		while ( getline( ifs , line ) )  
    		{
    			vect[i]=line;
    			ofs<<vect[i]<<"\n";
    			cout<<<<"test1  "<<vect[i]<<endl;      //affiche les valeurs de vect[i]
    		}; 
     
    	cout<<<<"test2  "<<vect[i]<<endl;     //affiche vect[i]
     
    	};
    Mais la problème, le deuxième affichage ne fonctionne pas, je crois que les valeurs de mon vecteur sont supprimées en sortant de la boucle "while" .
    Savez-vous comment faire pour les garder?

    Merci infiniment !

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut straight code.
    Exemple de code bourrin qui fait ce que j'en ai compris.

    J'utilise un modèle pipe & filter: analyse de ce qui est lu en entrée (stdin) et affichage de ce qui est (bien) parenthésé par les balises données en paramètres:
    cat fichier.txt | ./filter balise_1 balise_2 ...
    • Les balises à détecter sont dans une classe de type container pour minimiser les modifications à effectuer si on souhaite améliorer les fonctions de lookup.
    • La fonction qui analyse l'entrée est récursive: il faut bien empiler quelque part la balise en cours (et rien n'empeche d'avoir <b1> <b2> </b2> </b1>)
    • On suppose que les balises sont bien formées: en cas d'erreur, çà rale et stoppe.
    • C'est ce que j'appelle un hack (ou un prototype): code minimaliste, sans commentaires.


    - W





    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    # include <cstdio>
    # include <cstdlib>
    # include <cstring>
    # include <cstdarg>
     
    const int MAX_TOKEN=10;
    const char EOL='\n';
     
    class token_db {
      static token_db* db;
    private:
      int m_count;
      char** m_table;
      token_db() : m_count(0), m_table(NULL) {}
      token_db(const token_db&);
     ~token_db() {}
    public:
      void install (int count, char** table) {
        m_count = count;
        m_table = table;
      }
      bool lookup (char* key) {
        for (int i = 0; i < m_count; i++) 
          if (!strcmp(key, m_table[i]))
    	return true;
        return false;
      }
      static token_db* get_instance() {
        if (db == NULL) {
          db = new token_db();
        }
        return db;
      }
    };
    token_db *token_db::db = NULL;
     
    void fatal(char* fmt, ...)
    {
      va_list args;
      va_start(args, fmt);
      vfprintf(stderr, fmt, args);
      exit (EXIT_FAILURE);
    }
     
    char get_token (char* token, int max)
    {
      char ch;
      while (max > 0) {
        ch = fgetc(stdin);
        switch (ch) {
           case '>' : *token = 0;
           case EOF : return ch;
           default: *token++ = ch; max--;
        }
      }
      fatal ("*** token buffer overflow\n");
    }
     
    bool shoot_eol = false;
    void parse_input (char* token, bool filter)
    {
      char ch;
      char new_token[MAX_TOKEN];
      bool match;
     
      while (1) {
        if ( (ch = fgetc(stdin)) == EOF) {
          if (token != NULL)
    	 fatal ("***got EOF while parsing %s\n", token);
          return;
        }
        if (ch == '<') {
          if (token != NULL) {
    	ch = fgetc(stdin);
    	if (ch != '/')
    	  ungetc(ch, stdin);
    	else {
    	    ch = get_token (new_token, MAX_TOKEN);
    	    if (!strcmp (token, new_token)) {
    	      if (filter == true) {
    		printf("</%s>", token);
    		shoot_eol = true;
    	      }
    	      return;
    	    } else
    	      fatal("*** closing %s does not match opened %s\n",
    		    new_token, token);
    	}
          }
          if ( (ch = get_token (new_token, MAX_TOKEN)) == EOF)
    	  fatal ("*** got EOF while parsing %s\n", token);
          token_db* db = token_db::get_instance();
          match = db->lookup (new_token);
          if (filter || match) 
    	printf("<%s>", new_token);
          parse_input (new_token, match ? true : filter);
        } else {
          if (filter == true) 
    	putc(ch, stdout);
          else if (ch == EOL && shoot_eol) {
    	putc (EOL, stdout);
    	shoot_eol = false;
          }
        }
      }
    }
     
    int main (int argc, char **argv)
    {
      token_db* db = token_db::get_instance();
      db->install (argc - 1, &argv[1]);
      parse_input (NULL, false);
      return EXIT_SUCCESS;
    }
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    wiztricks >> Le code que tu donne marche peut-être très bien et est peut être très sécurisé, mais c'est du C à la sauce C++. (et c'est moche)

    Edit: par contre +1 pour tes remarques.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  14. #14
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut
    merci beaucoup, j'imagine que vous passez tous beaucoup de temps à faire cela, mais il n'y a pas de possibilité pour "sauvegarder" le vecteur que j'ai crée dans la boucle while?

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    [QUOTE=Davidbrcz;3485174]wiztricks >> Le code que tu donne marche peut-être très bien et est peut être très sécurisé, mais c'est du C et non du C++.

    Je suis globalement d'accord, même s'il comporte des constructions spécifiques à C++. Mais je ne suis pas certain que le problème mérite plus que d'utiliser C++ comme un meilleur C.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par cre31400 Voir le message
    merci beaucoup, j'imagine que vous passez tous beaucoup de temps à faire cela, mais il n'y a pas de possibilité pour "sauvegarder" le vecteur que j'ai crée dans la boucle while?
    2 heures... Mais beaucoup de temps passé à découvrir Eclipse CDT.
    Pour ce qui est de votre code, je suis désolé mais je n'ai pas encore compris en quoi ce que vous cherchiez à faire allait dans le bon sens.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  17. #17
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut
    Merci vraiment...
    Bon je ne sais pas utiliser le XML, aucune idée là-dessus...donc je me rabats sur du C++ .

    J'ai un fichier, je vous le copie exactement comme je l'ai :

    <name>Scenario 3.1.kmz</name>
    <name>3.1</name>
    <name>LLF</name>
    <name>GLOB31</name>
    <name>GERAZN</name>
    <coordinates>-0.06805555555555556,43.22,0</coordinates>
    <name>LOUB2</name>
    <coordinates>1.537166666666667,43.02866666666667,0</coordinates>
    <name>LOUB1</name>
    <coordinates>1.611666666666667,43.01833333333333,0</coordinates>
    <name>DUNA</name>
    <coordinates>1.785,43.04,0</coordinates>
    <name>AGOUT</name>

    Bon ca continue un peu encore.
    Moi je ne veux garder de ce fichier, que les couples par exemple :
    <name>GERAZN</name>
    <coordinates>-0.06805555555555556,43.22,0</coordinates>
    qui correspondent à un point et ses coordonnées.

    Je veux me débarasser donc des 4 premières lignes ici (mais ce nombre de lignes inutiles change selon le fichier que j'exploite, donc il me faut un programme qui marche quelque soit le fichier...)
    Donc dans ma tête mon algo c'est : Je prends une ligne i, si il y a <name>, je regarde la ligne i+1 . Si il y a <coordinate> je garde la ligne i, sinon je la supprime (je réinitialise l'itération à chaque fin de cyle )

    Cette méthode m'assure de me débarasser des lignes superflues ...
    Je n'ai pas trouvé d'autres moyens ...

    Bref, c'est plutôt bourin , je suis totalement d'accord, mais je fais ce que je peux ...

    Si ma petite explication vous a inspiré, je suis tout ouï !!

  18. #18
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 44
    Points : 19
    Points
    19
    Par défaut
    bon je pense avoir trouvé (pas tout seul) le moyen donc d'indicer les lignes d'un fichier texte par exemple toto.txt qui comporte on dira ici moins de 50 lignes :

    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
     
    #include <vector>
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <fstream>
    #include <algorithm>
    using namespace std;
     
    int main(int argc, char* argv[])
    {
        vector<string> vect; 
        ifstream ifs(  "toto.txt"  );
        string line;	
     
    //------boucle pour lire les lignes et les affecter aux lignes du vecteur-----
     
        while(getline(ifs, line))
    	{
    	     vect.push_back(line);
    	};		
    //--------------boucle pour afficher les valeurs du vecteur-----------------
     
        for(size_t i=0;i<vect.size(); ++i) 
    	{
    	    cout << vect[i] << "\n";
    	};
     
     
    return 0;
    }
    Bon je ne pense qu'il y ait besoin de toutes les includes, mais ca fonctionne !
    Merci à tous pour votre temps et tous vos conseils !!!

    a+

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut straight code - V2
    Ca sort:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ cat essai.txt | ./filter name coordinates
    <name>GERAZN</name>
    <coordinates>-0.06805555555555556,43.22,0</coordinates>
    <name>LOUB2</name>
    <coordinates>1.537166666666667,43.02866666666667,0</coordinates>
    <name>LOUB1</name>
    <coordinates>1.611666666666667,43.01833333333333,0</coordinates>
    <name>DUNA</name>
    <coordinates>1.785,43.04,0</coordinates>
    Je suis resté sur la même idée "pipe & filter" que ce matin.
    A la base, je n'aime pas l'idée de lire un nombre indéfini de lignes alors qu'on cherche à reconnaitre et extraire des séquences de la forme AB du flot, ie après avoir lu A, s'il est suivi de B alors j'affiche AB.
    Note: en XML, les unités d'information sont encadréee par des balises et ne correspondent pas forcément à des lignes.

    Plutôt que de tout jeter, j'ai spécialisé le code de ce matin:
    • pas d'écriture avant d'avoir lu la sequence "valide" => stocker dans un buffer en attendant d'avoir lu la séquence attendue,
    • adaptation de "token_db" pour reconnaitre la suite de balises attendues (gérer l'état de l'automate qui reconnait A -> B -> nil).



    - W

    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    # include <cstdio>
    # include <cstdlib>
    # include <cstring>
    # include <cstdarg>
    # include <cctype>
     
    const int MAX_TOKEN=30;
    const char EOL='\n';
     
    class token_db {
      static token_db* db;
    private:
      int    m_count;
      char** m_table;
      int    m_seq;
      token_db() : m_count(0), m_table(NULL), m_seq(0) {}
      token_db(const token_db&);
     ~token_db() {}
    public:
      void install (int count, char** table) {
        m_count = count;
        m_table = table;
      }
      bool match_expected (char* key) {
        if (!strcmp (key, m_table[m_seq]))
          return true;
        return false;
      }
      int get_seq() { return m_seq; }
      void clear_seq() { m_seq = 0; }
      void next_seq() { m_seq++; }
      bool last_seq() { return (m_seq == m_count) ? true : false; }
      bool lookup (char* key) {
        for (int i = 0; i < m_count; i++) 
          if (!strcmp(key, m_table[i]))
    	return true;
        return false;
      }
      static token_db* get_instance() {
        if (db == NULL) {
          db = new token_db();
        }
        return db;
      }
    };
    token_db *token_db::db = NULL;
     
    void fatal(char* fmt, ...)
    {
      va_list args;
      va_start(args, fmt);
      vfprintf(stderr, fmt, args);
      exit (EXIT_FAILURE);
    }
     
    class buffer {
    private:
      char *m_buffer;
      int  m_size;
      char *m_ptr;
      char *m_eob;
    public:
      buffer(int size) : m_size(size) {
        m_buffer = new char[size];
        m_ptr = m_buffer;
        m_eob = m_buffer + size;
      }
      ~buffer() {
        delete m_buffer;
      }
      void zero() { m_ptr = m_buffer; }
      void put(char ch) { 
        *m_ptr++ = ch; 
        if (m_ptr == m_eob) 
          fatal("*** buffer overflow\n");
      }
      void put (char* s) {
        while (*s != 0)
          put(*s);
      }
      void flush() {
        fwrite(m_buffer, sizeof(char), m_ptr - m_buffer, stdout);
        zero();
      }
      void putfmt(char* fmt, ...)
    {
      va_list args;
      va_start(args, fmt);
      int length = vsnprintf(m_ptr, m_eob - m_ptr, fmt, args);
      if (length == -1)
          fatal("*** buffer overflow\n");
      m_ptr += length;
    }
     
    };
     
    char get_token (char* token, int max)
    {
      char ch;
      while (max > 0) {
        ch = fgetc(stdin);
        switch (ch) {
           case '>' : *token = 0;
           case EOF : return ch;
           default: *token++ = ch; max--;
        }
      }
      fatal ("*** token buffer overflow\n");
    }
     
     
    void parse_input (char* token, bool filter, buffer* p_buf)
    {
      char ch;
      char new_token[MAX_TOKEN];
      bool match;
      token_db* db = token_db::get_instance();
     
      while (1) {
        if ( (ch = fgetc(stdin)) == EOF) {
          if (token != NULL)
    	 fatal ("***got EOF while parsing %s\n", token);
          return;
        }
        if (ch == '<') {
          if (token != NULL) {
    	ch = fgetc(stdin);
    	if (ch != '/')
    	  ungetc(ch, stdin);
    	else {
    	    ch = get_token (new_token, MAX_TOKEN);
    	    if (!strcmp (token, new_token)) {
    	      if (filter == true) {
    		p_buf->putfmt("</%s>\n", token);
    	      }
    	      if (db->match_expected(new_token)) {
    		db->next_seq();
    		if (db->last_seq()) {
    		  p_buf->flush();
    		  db->clear_seq();
    		}
    	      }
    	      return;
    	    } else
    	      fatal("*** closing %s does not match opened %s\n",
    		    new_token, token);
    	}
          }
          if ( get_token (new_token, MAX_TOKEN) == EOF)
    	  fatal ("*** got EOF while parsing %s\n", token);
          match = db->match_expected(new_token);
          if (filter || match) 
    	p_buf->putfmt("<%s>", new_token);
          if (!match) {
    	p_buf->zero();
    	db->clear_seq();
          } else
    	parse_input (new_token, (match) ? true : filter, p_buf);
        } else {
          if (filter == true) 
    	p_buf->put(ch);
          else if (db->get_seq() > 0 && isgraph(ch)) {
    	p_buf->zero();
    	db->clear_seq();
          } 
        }
      }
    }
     
    int main (int argc, char **argv)
    {
      buffer p_buf(512);
      token_db* db = token_db::get_instance();
      db->install (argc - 1, &argv[1]);
      parse_input (NULL, false, &p_buf);
      return EXIT_SUCCESS;
    }
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

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

Discussions similaires

  1. Programme pour compter les lignes d'un fichier texte?
    Par codon21 dans le forum Windows
    Réponses: 1
    Dernier message: 19/03/2009, 07h36
  2. Relire les lignes d'un fichier texte
    Par hassna.kaibous dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 03/06/2008, 12h52
  3. Supprimer les lignes d'un fichier texte
    Par radhwene dans le forum Langage
    Réponses: 1
    Dernier message: 20/06/2007, 11h01
  4. Boucle qui parcourt tout les ligne d'un fichier text
    Par accro-macro dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 10/05/2007, 20h21
  5. Réponses: 2
    Dernier message: 19/09/2006, 21h34

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