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.