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 :

Traitement fichier txt


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 38
    Par défaut Traitement fichier txt
    Bonjour à tous,

    J'ai un petit problème avec un fichier txt, j'ai un fichier txt qui a cette forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    BT     1
    BN bonjour
    BG  
    BU  
    BB  
    BM NH
    BP A:001 P01:test P02:00001400 P03:00001400 P09:string
    KS toto tata
    BT       20
    ....
    Ce bloc peut se répéter N fois dans le fichier txt. Je fait donc une boucle while afin de parcourir chacune de mes lignes avec ifstream, et j'utilise boost afin de séparer ma ligne sur chaque espace, comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while(std::getline(fichier, line))
    { 
        std::vector<std::string> tokens;
        boost::split(tokens, line, boost::is_any_of(" "));
    }
    Moi ce que j'aimerais faire c'est récupérer un tableau de ligne pour chaque section. Une section commence par BT et dès que je retombe sur un BT j'ai une nouvelle section. Mon while est donc :

    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
    while(std::getline(fichier, line))
    { 
        std::vector<std::string> tokens;
        boost::split(tokens, line, boost::is_any_of(" "));
     
        if(tokens[0].compare("BT") == 0)
        {
              //nouvelle section detecte ici                 
     
        }
        else if(tokens[0].compare("BP") == 0)    
        {
     
        }
        else 
        {
     
        } 
    }
    Problème je ne sais pas trop comment faire pour avoir au final quelque chose comme ça :

    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
    [0] => Array
                    (
                        [0] => BT     1
     
                        [1] => BN poteau
     
                        [2] => BG  
     
                        [3] => BU  
     
                        [4] => BB  
     
                        [5] => BM NH
     
                        [6] => BP A:001 P01:test P02:00001400 P03:00001400 P09:string
     
                        [7] => KS toto tata
                   )
    [1] => Array(
                        [1] => BT       20
     
                        [2] =>  ...........
     
                   )

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut ajout du lien vers string_view
    salut,

    Je vais partir du principe que le nombre de lignes de chaque section est inconnu qu'il se peut que tu aies parfois 5 lignes entre deux BT et que, à d'autres moments, tu en aies... 10 (par exemple). Cela permettra d'avoir quelque chose de bien plus général, qui fonctionnera aussi si le nombre de ligne entre deux BT est toujours le même

    Et je vois deux solutions :
    Soit tu remplis effectivement un tableau avec les chaines (exactement de la manière dont tu le fais), et tu t'arranges pour vérifier à chaque ligne si tu as de nouveau BT, avant de décider si tu rajoute le tout dans le tableau en cours ou si tu ... rajoute le tableau précédant dans un tableau de... tableau de chaine de caractères avant de commencer à remplir un nouveau tableau.
    Soit tu sépare clairement la notion de ligne de tableau et celle de "section", en te disant que tu peux mettre toutes les chaines dans un seul et unique tableau et maintenir, "à coté de ce tableau", un autre tableau qui contiendra l'indice auquel se trouvent les différentes chaines de début de section.

    La première solution pourrait prendre une forme proche de
    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
    std::vector<std::vector<std::string>> result; // un tableau contenant un tableau de chaines de caractères
                                                                                                                                                                              // correspondant chaque fois à une section
     
    std::vector<std::string> temp; // un tableau "temporaire" pour récupérer les chaines de caractères
                                                    // de la ligne
    std::string read; // la chaine de caractères extraite du flux
    while(std::getline(read, ifs)) { // tant qu'il y a quelque chose à extraire 
        std::vector<std::string> tokens;
        boost::split(tokens, line, boost::is_any_of(" "));
        if(tokens[0]=="BT"){ // si on a le symbole de "début de section
            result.push_back(temp); // on ajoute ce qui a été extrait les lignes précédantes
            temp=tokens; // et la ligne que l'on vient d'extraire devient le début de la section suivante
        else // sinon
            temp.insert(temp.end(),tokens.begin(),tokens.end()); // on ajoute le contenu de la ligne aux lignes précédantes
    }
    NOTA : il est tout à fait possible d'éviter le recours à la variable temp, mais j'ai trouvé que c'était plus lisible sous cette forme

    La deuxième solution est encore plus simple, car il "suffit" de vérifier le premier élément du tableau rempli par boost et de prendre la taille du tableau final, sous une forme proche de
    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
     
    std::vector<std::string> result; // le tableau contenant toutes les chaines de caractères
    std::vector<size_t> sectionStart; // et celui contenant l'indice de début des sections
    std::string read; // la chaine d'extraction
    while(std::getline(read, ifs)){ // pareil que plus tot
        std::vector<std::string> tokens;          // DITTO
        boost::split(tokens, line, boost::is_any_of(" ")); // DITTO
        if(tokens[0]=="BT"){ // DITTO
            sectionStart.push_back(result.size()); // on sauvegarde la taille du tableau de résultat
        }
        // quoi qu'il advienne, on ajoute le contenu de tokens à result
        result.insert(result.end(), tokens.begin(), tokens.end());
        // et on vide tokens (je ne sais jamais si boost le fait ou non... autant garantir que ce sera fait)
        tokens.clear();
    }
    Les deux solutions ont leurs avantages et leurs inconvénients. Il faudra donc voir laquelle est la plus adaptée à ta situation propre

    NOTA: si tu dispose de C++14, tu peux peut être envisager le recours à std::experimental::string_view qui pourrait -- peut-être -- te permettre des trucs sympa
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. traitement fichier .txt
    Par steven78700 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 12
    Dernier message: 15/02/2011, 05h53
  2. [PERL]: Help script traitement fichier txt tabulaire
    Par Piccolupo13 dans le forum Langage
    Réponses: 2
    Dernier message: 21/08/2007, 20h37
  3. [CSV] Traitement fichiers txt/csv avec php
    Par cirtey dans le forum Langage
    Réponses: 4
    Dernier message: 26/01/2007, 16h46
  4. Traitement fichier .txt (gestion des '','')
    Par clemasson dans le forum Access
    Réponses: 1
    Dernier message: 11/12/2006, 15h26
  5. Optimiser traitement fichier [.txt]
    Par Metallic-84s dans le forum Langage
    Réponses: 14
    Dernier message: 16/03/2006, 13h33

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