Récupérer les chaînes comprises entre 2 balises

Résolu
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015 - 6 mai 2011 à 16:25
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015 - 6 mai 2011 à 18:09
bonjour,
je veux récupérer de mon texte toutes les chaines comprises entre <S> et </S>, j'espère que c'est possible et que vous pouvez m'aider à corriger ce code pour arriver au résultat voulu:
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include 

std::string RecupererChaine (const std::string& filename)
{ std::string ch, chaine = "";
  int i = 1;
  std::ifstream text(filename.c_str());
  if (!text)
   {
     std::cerr << "Unable to open the file: " << filename << std::endl;
     return 0;
   }

  while (text>> ch)
  {
    if (ch == "<S>")
{
  i = 1;
  continue;
        }
else if (i && ch == "</S>")
        {
  i = 0;
  continue;
}

if (i)
  chaine = chaine + " " + ch;
  }
  return chaine;
}
int main(void)
{
  std::ofstream ofs ("out.txt");
  ofs << SuppBalises("in.txt" );
  return 0;

}

3 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
6 mai 2011 à 17:49
Tu n'étais pas très loin. C'est pas mal.

Quelques remarques:
- string.h et stdio.h n'ont pas de sens ici
- main(void) => main(), en C++ contrairement au C, on ne met pas void pour indiquer qu'une fonction ne prend pas d'argument.
- chaine chaine + ch> Pour des concaténations, on préfère utiliser une classe de string bufferisés plutôt que des strings.
- Les "continue" ne me gêne pas, mais si tu peux les éviter, je te conseille de le faire.

Le souci avec ton code, c'est que si on a une balise <S> qui touche un mot, alors tu ne le voit pas.
Exemple: <S>Coucou </S>, sera découpé en "<S>Coucou" et "</S>", et donc tu ne verras pas de "<S>" tout seul.
Il te faut donc repérer ces cas.

Au final, tu as plusieurs cas:
- Cas 1: <S>mot</S>: Extraction du milieu (extractMiddle).
- Cas 2: <S>mot </S>: Extraction de la fin, quand le mot touche la balise de début (extractBegin).
- Cas 3: <S> mot</S>: Extraction du début, quand le mot touche la balise de fin (extractEnd).
- Cas 4: <S> mot </S>: Cas normal que tu as déjà géré, rien de particulier.

Je te propose ce code (il peut être encore légèrement optimisé, mais je souhaitais d'abord qu'il soit simple à comprendre).
#include 
#include <fstream>
#include <sstream>

namespace
{
  std::string
  extractMiddle(const std::string& s)
  {
    size_t begin = s.find("<S>") + 3;
    size_t end = s.rfind("</S>");
    return s.substr(begin, end - begin);
  }

  std::string
  extractBegin(const std::string& s)
  {
    size_t begin = s.find("<S>") + 3;
    return s.substr(begin);
  }

  std::string
  extractEnd(const std::string& s)
  {
    size_t end = s.rfind("</S>");
    return s.substr(0, end);
  }

  std::string
  getString(const std::string& filename)
  {
    std::string ch = "";
    std::ostringstream res;
    bool active = false;
    std::ifstream text(filename.c_str());
    if (!text)
    {
      std::cerr << "Unable to open the file: " << filename << std::endl;
      return 0;
    }

    while (text >> ch)
    {
      if (ch.find("<S>") != std::string::npos && ch.rfind("</S>") != std::string::npos)
res << " " << extractMiddle(ch);
      else if (ch.find("<S>") != std::string::npos)
      {
if (ch != "<S>")
  res << " " << extractBegin(ch);
active = true;
      }
      else if (active && ch.rfind("</S>") != std::string::npos)
      {
if (ch != "</S>")
  res << " " << extractEnd(ch);
active = false;
      }
      else if (active)
res << " " << ch;
    }
    return res.str();
  }
}

int main()
{
  std::cout << getString("in.txt" ) << std::endl;
  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
3
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
6 mai 2011 à 16:30
Désolée, ilya une faute dans le main, c'est RecupererChaine pas SuppBalises
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
6 mai 2011 à 18:09
c'est vraiment professionnel, je vous remercie pour vos conseils et pour tous ces détails.
merci infiniment CptPingu.
0
Rejoignez-nous