cs_mervat
Messages postés90Date d'inscriptionsamedi 5 juin 2010StatutMembreDernière intervention 6 mars 2015
-
6 mai 2011 à 16:25
cs_mervat
Messages postés90Date d'inscriptionsamedi 5 juin 2010StatutMembreDerniè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;
}
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023123 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/portfoliohttp://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question