Réponse acceptée !
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).
Code C/C++ :
#include <iostream>
#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
Merci d'utiliser Réponse acceptée si un post répond à votre question