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

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

}
Afficher la suite 

Votre réponse

3 réponses

Meilleure réponse
Messages postés
3830
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
19 novembre 2018
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

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 97 internautes ce mois-ci

Commenter la réponse de cptpingu
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
Désolée, ilya une faute dans le main, c'est RecupererChaine pas SuppBalises
Commenter la réponse de cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
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.