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:
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:
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 ;)