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 :

Probleme au niveau d'un parser


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2012
    Messages : 56
    Points : 38
    Points
    38
    Par défaut Probleme au niveau d'un parser
    Bonjour,

    mon parser ne fonctionne pas pour tous les fichiers, dans certains cas, des lignes disparaissent.. Avez-vous éventuellement des suggestions pour l'améliorer? Il prend en compte tout type de délimiter, assez pratique quand je veux mettre des ';' ou des '\t' selon l'extension du fichier..

    Le but est de de parser le fichier et de créer une matrice à double dimension afin d'effectuer toute une série de traitements sur les données.

    voici le code:

    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
     
        #ifndef CSVPARSER_HPP
        #define CSVPARSER_HPP
     
        #include <iterator>
        #include <functional>
     
        /// @brief Représente un parseur de CSV.
        /// La classe accepte tout format itérable. En conséquence il est possible de parser un std::vector<int>
        /// en définissant par exemple 0 comme délimiteur de cellule, 1 comme délimiteur de ligne et 2 comme
        /// délimiteur d'échappement
        template <class T>
        class CsvParser
        {
        private:
                typename T::value_type                  m_cell_delim;
                typename T::value_type                  m_line_delim;
                typename T::value_type                  m_escp_delim;
                typename T::const_iterator              m_position;
                typename T::const_iterator              m_end;
                unsigned long                                   m_row;
                unsigned long                                   m_col;
                unsigned long                                   m_cell;
                std::function<bool ()>                  m_parse;
     
                /// @brief État "normal", on accepte tout caractère qui n'est pas un délimiteur.
                /// @returns true pour indiquer qu'il faut accepter l'élément courant, sinon false.
                /// Si le délimiteur d'échappement est rencontré, on change d'état, la fonction de parse active
                /// devient parse_escaped.
                bool parse_default()
                {
                        if (m_position != m_end)
                        {
                                typename T::value_type i = *m_position;
     
                                if (i == m_cell_delim)
                                {
                                        m_position++;
                                        m_col++;
                                        m_cell++;
                                        return false;
                                }
     
                                if (i == m_line_delim)
                                {
                                        m_position++;
                                        m_col = 0;
                                        m_cell++;
                                        m_row++;
                                        return false;
                                }
     
                                if (i == m_escp_delim)
                                {
                                        m_position++;
                                        m_parse = std::bind(&CsvParser<T>::parse_escaped, this);
                                        return m_parse();
                                }
                                return true;
                        }
                        return false;
                }
     
                /// @brief État "echapé", on accepte tout caractère qui n'est pas un délimiteur d'échappement.
                /// @returns true pour indiquer qu'il faut accepter l'élément courant, sinon false.
                /// Si le délimiteur d'échappement est rencontré, on vérifie s'il est doublé, si oui on accepte le caractère
                /// sinon on change d'état, la fonction de parse active devient parse_default.
                bool parse_escaped()
                {
                        if(m_position != m_end)
                        {
                                typename T::value_type i = *m_position;
                                if (i == m_escp_delim)
                                {
                                        m_position++; // On passe à l'élément suivant
                                        if (m_position != m_end && *m_position == m_escp_delim) return true;
     
                                        m_parse = std::bind(&CsvParser<T>::parse_default, this);
                                        return m_parse();
                                }
                                return true;
                        }
                        return false;
                }
     
        public:
                /// @brief Construit un parseur CSV.
                /// @param[in] cell_delim Le délimiteur de cellule, généralement une tabulation, une virgule ou un point-virgule quand la donnée à lire est du texte.
                /// @param[in] line_delim Le délimiteur de ligne, généralement un retour chariot quand la donnée à lire est du texte.
                /// @param[in] espc_delim Le délimiteur d'échappement, générallement un guillemet quand la donnée à lire est du texte.
                CsvParser(const T& value, typename T::value_type cell_delim, typename T::value_type line_delim, typename T::value_type escp_delim)
                        : m_position(std::begin(value))
                        , m_end(std::end(value))
                        , m_row(0)
                        , m_col(0)
                        , m_cell(0)
                        , m_cell_delim(cell_delim)
                        , m_line_delim(line_delim)
                        , m_escp_delim(escp_delim)
                        , m_parse(std::bind(&CsvParser<T>::parse_default, this))
                {
                }
     
                /// @brief Obtient la ligne en cours de lecture.
                unsigned long currentRow() const { return m_row; }
     
                /// @brief Obtient la colonne en cours de lecture.
                unsigned long currentCol() const { return m_col; }
     
                /// @brief Obtient la cellule en cours de lecture.
                unsigned long currentCell() const { return m_cell; }
     
                /// @brief Permet de vérifier si le parser à encore des données à lire.
                explicit operator bool() const { return m_position != m_end; }
     
                /// @brief Obtient la valeur suivante.
                T ReadNext()
                {
                        T value;
                        while(m_parse())
                        {
                                value.push_back(*m_position);
                                m_position++;
                        }
                        return value;
                }
     
                /// @brief Permet une syntaxe du style p >> c1 >> c2;
                CsvParser<T>& operator>>(T& value)
                {
                        value = ReadNext();
                        return *this;
                }
        };
     
        #endif // CSVPARSER_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
    25
    26
    27
    28
     
        #define CELL_DELIMITER '\t'  
        #define LINE_DELIMITER '\n'
        #define ESCAPE_DELIMITER '*'
     
        typedef std::vector<std::vector<std::string>>                           table;
        typedef table::value_type                                               row;
     
        /// @brief Parse un fichier et retourne une table équivalente.
        /// @param[in] filename Le fichier à parser.
        /// @returns La table résultante.
        table parse(std::string& filename, std::string& content, const char& cell_delimiter, const char& line_delimiter, const char& escape_delimiter)
        {
                bool process = true;
                table t;
                CsvParser<std::string> parser(content, cell_delimiter, line_delimiter, escape_delimiter);
                while (process)
                {
                        std::vector<std::string> line;
                        auto ln = parser.currentRow();
                        while (parser && parser.currentRow() == ln)
                                line.push_back(parser.ReadNext());
                        t.push_back(line);
                        if (!parser) process = false;
                }
     
                return t;
        }
    Merci.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par bowow Voir le message
    mon parser ne fonctionne pas pour tous les fichiers, dans certains cas, des lignes disparaissent...
    De manière apparemment aléatoire, ou selon un schéma répétitif (genre une ligne sur deux) ?

Discussions similaires

  1. Débutant probleme au niveau "tutorial java"
    Par carton dans le forum Java ME
    Réponses: 3
    Dernier message: 22/07/2006, 09h54
  2. Probleme au niveau de la connexion de tomcat avec oracle8i
    Par hamska2 dans le forum Tomcat et TomEE
    Réponses: 1
    Dernier message: 08/05/2006, 00h53
  3. [JMF] Problème au niveau de RTP
    Par Alienx dans le forum Multimédia
    Réponses: 2
    Dernier message: 05/03/2006, 15h50
  4. [Thread] petit problème au niveau du reveil d'un thread
    Par sagitarium dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 13/01/2006, 11h35
  5. PROBLEME haut niveau BACKUP
    Par Dev_Michael dans le forum Administration
    Réponses: 7
    Dernier message: 10/03/2005, 15h32

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