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

cs_mervat 90 Messages postés samedi 5 juin 2010Date d'inscription 6 mars 2015 Dernière intervention - 6 mai 2011 à 16:25 - Dernière réponse : cs_mervat 90 Messages postés samedi 5 juin 2010Date d'inscription 6 mars 2015 Dernière intervention
- 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;

}
Afficher la suite 

Votre réponse

3 réponses

Meilleure réponse
cptpingu 3797 Messages postés dimanche 12 décembre 2004Date d'inscription 13 août 2018 Dernière intervention - 6 mai 2011 à 17:49
3
Merci
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

Merci cptpingu 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 74 internautes ce mois-ci

Commenter la réponse de cptpingu
cs_mervat 90 Messages postés samedi 5 juin 2010Date d'inscription 6 mars 2015 Dernière intervention - 6 mai 2011 à 16:30
0
Merci
Désolée, ilya une faute dans le main, c'est RecupererChaine pas SuppBalises
Commenter la réponse de cs_mervat
cs_mervat 90 Messages postés samedi 5 juin 2010Date d'inscription 6 mars 2015 Dernière intervention - 6 mai 2011 à 18:09
0
Merci
c'est vraiment professionnel, je vous remercie pour vos conseils et pour tous ces détails.
merci infiniment CptPingu.
Commenter la réponse de cs_mervat

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.