IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Remplacement de chaîne de caractère


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 5
    Par défaut Remplacement de chaîne de caractère
    Bonjour,

    Je vous explique, sur le programme que l'on développe , on rentre une phrase dans un TEdit.
    J'ai installé par la suite deux TexBox, l'une sert à trouver ses caractères dans la chaine saisie pour les remplacer par ceux de la 2em TexBox.
    J'ai écrit sa mais sa ne fonctionne pas et je ne comprend pas


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    void __fastcall TForm1::Button5_remplaceClick(TObject *Sender)
    {
     int n=0;
     int k;
     char LettreRepere[80];
     int TailleRep =  Form1->Edit_retirer->Text.Length();
     if (TailleRep< 80 )
           for (int i=0 ; i<=TailleRep ; i++)
                    LettreRepere[i]=Form1->Edit_retirer->Text.c_str()[i];
     char LettreRemplace[80];
     int TailleRem = Edit_remplace->Text.Length();
     if (TailleRem< 80 )
           for (int i=0 ; i<=TailleRem ; i++)
                    LettreRemplace[i]=Form1->Edit_remplace->Text.c_str()[i];
     char ChaineConvertie[100];
     for (int i=0; texte[i]!=0; i++)
            {
             if( texte[i]==LettreRepere[0])
                    for (int j=0; j<TailleRep; j++)
                            if(texte[i+j]==LettreRepere[j])
                                    n++;
             k=0;
             if (n==TailleRep)
                    for (k; k<TailleRem; k++)
                            ChaineConvertie[i+k]=LettreRemplace[k];
                    else ChaineConvertie[i+k]= texte[i];
             k+=i;
            }
     ChaineConvertie[k]=0;
     Form1->Edit_chaineSaisie->Text=ChaineConvertie;
    }
    Merci d'avance pour votre aide!
    Pour un exemple plus concret, Voila le programme Exemple en pièce jointe.
    Fichiers attachés Fichiers attachés

  2. #2
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    Si vous opérez en C++, pourquoi diable utiliser des tableaux de caractères plutôt que des std::string et/ou des std::vector ? Vous cherchez vraiment les complications et les ennuis...

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Tout à fait d'accord. Voici un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #include <iostream>
    #include <string>
     
    int main()
    {
    	std::string phrase("Bonjour monsieur");
    	std::string achercher("oum");
    	std::string aremplacer("ain");
     
    	if( achercher.size() != aremplacer.size() )
    		return 1; // Erreur, chaînes mal formées
     
    	std::string::const_iterator caractere1, caractere2;
    	caractere2 = aremplacer.begin();
    	for( caractere1 = achercher.begin(); caractere1 != achercher.end(); caractere1++)
    	{
    		size_t lookHere = 0;
    		size_t foundHere;
    		std::string from(caractere1,caractere1+1);
    		std::string to(caractere2,caractere2+1);
     
    		while((foundHere = phrase.find(from, lookHere)) != std::string::npos)
    		{
    			phrase.replace(foundHere, from.size(), to);
    			lookHere = foundHere + to.size();
    		}
    		caractere2++;
    	}
     
    	std::cout << phrase << std::endl;
     
        return 0;
    }
    Ce programme affiche "banjair nansieir". C'est pas le pied au niveau performance mais je doute que ça soit vraiment important ici.

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Remplacer une chaine par un autre ou un caractère par un autre dans une chaine : std::string::replace(), dans <string>

    Ramplacer un caractère par un autre dans un vector<char> : std::replace, dans <algorithm>.

    Et pour faire un remplacement du type du second mais plus général, on peut soit utiliser std::replace dans une boucle (pas forcément une bonne idée), soit utiliser std::transform avec un foncteur bien choisi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    #include <algorithm> // pour std::transform
    #include <stdexcept> // pour std::invalid_argument
     
    struct replace_all_functor
    {
      std::string m_in;
      std::string m_out;
     
      replace_all_functor(const std::string& in, const std::string& out)
      : m_in(in), m_out(out)
      {
        if (m_in.length() != m_out.length())
        {
          throw std::invalid_argument("in et out doivent faire la même taille");
        }
      }
     
      char operator()(char in)
      {
        std::size_t pos = m_in.find(in);
        return (pos == std::string::npos ? in : m_out[pos]);
      }
    };
     
    template <class InIt, class OutIt>
    void replace(InIt first, InIt last, OutIt out, const std::string& from, const std::string& to)
    {
      std::transform(first, last, out, replace_all_functor(from, to));
    }
    L'algorithme est nécessairement en O(n^2) (std::transform --> O(n) + recherche dans la chaine m_in en O(n) aussi). Il est possible de modifier le foncteur pour le passe en O(n), en construisant une liste de correspondance entre les caractères à remplacer et les caractères de remplacement, mais le code devient nettement moins trivial, et ce n'est pas toujours possible.

    Attention à la locale courante : en fonction de celle-ci, il peut être avantageux de passer d'abord les chaines en std::wstring (double attention : à moins qu'il n'ai été corrigé, l'article de la FAQ C++ qui traite de ce point particulier contient une erreur ; je vous engage plutôt a lire mon article sur le sujet)
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Joli, mais le pauvre btsIris59 va être perdu

  6. #6
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Joli, mais le pauvre btsIris59 va être perdu
    C'est pour ça que j'ai écrit le code en entier. Comme ça, il peut le copier sans vergogne
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  7. #7
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    Attention à la typo dans ton code, remplacer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      replace_all(const std::string& in, const std::string& out)
    par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      replace_all_functor(const std::string& in, const std::string& out)

  8. #8
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par ptyxs Voir le message
    Attention à la typo dans ton code, remplacer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      replace_all(const std::string& in, const std::string& out)
    par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      replace_all_functor(const std::string& in, const std::string& out)
    Ah voui. Je corrige tout de suite.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 5
    Par défaut
    A oui j'ai oublié de préciser que c'est du PDO sur Borland builder c++ Donc se moyen de programmation ne passe pas sur ce logiciel si je ne puis dire... useless^^
    Et je ne suis pas interesser par le recopiage mais par la compréhension. (merci quand même)
    Et je suis obliger de travaillez sur mon tableau texte[] car j'ai mis dedans la chaîne saisie et qu'on doit travaillez sur ce tableau avec tous les boutons...
    Donc je ne peut me servir des string comme dans vos exemple.

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Citation Envoyé par btsIris59 Voir le message
    Donc je ne peut me servir des string comme dans vos exemple.
    Faux, tu peux construire une string directement à partir d'un tableau de char. Par contre je ne sais effectivement pas si tu as accès à la STL. Le contraire serait tout de même étonnant.

    Quant à la compréhension ma foi, mon code est un poil plus simple à comprendre, mais dans tous les cas il te faudra te plonger dans la doc de std::string. Il n'y a pas une seule manière de résoudre ton problème.

    Tu tiens absolument à passer par tes tableaux ?

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 5
    Par défaut
    Non Mais dans ce cas je devrais transférer mon tableau dans un string.
    Si la logique est bonne:
    char texte[80]="Bonne Année";
    String receptacle;
    receptacle=texte;

    Après il faut reprendre l'idée de vos exemple et retranscrire tous sa dans borland(pas facile)...

    Mais bon, si on suit l'idée de notre prof, je doit juste travaillé sur mon tableau...
    Et surtout dans ton exemple tu retire le cas ou la chaine à rajouter est plus grande ou plus petite que la chaine à rechercher, or si la chaine à rechercher fait 3 lettres, la chaine a remplacer peut en faire 5.

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    D'accord, alors ça veut dire que je n'ai pas compris ton algorithme. Peux-tu être plus précis sur ce que tu veux remplacer et par quoi ? Parce que si ça se trouve, c'est encore plus simple...

    Donne nous un exemple de la phrase, de la chaîne "à remplacer", de la chaîne de "remplacements" et du résultat attendu.

    Ce que j'avais compris : remplace("abcd","ac","xy") => "xbyd"

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 5
    Par défaut
    C'est pour sa que j'avais joint l'executable du programme exemple.
    Par exemple:
    Phrase saisie: Bonne Année
    Chaine a reperer: nn
    Chaine a remplacer : ace
    Résultat: Boacee Aaceée

    Ce sont des lettres qui s'enchaine car à la base c'est pour remplacer un mot avec un autre mais sa peu aussi juste récupérer une syllabe par exemple et la remplacer par ce qu'on veut.

  14. #14
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Il y a un exemple tout fait dans la doc de la STL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    string& replaceAll(string& context, const string& from, const string& to)
    {
        size_t lookHere = 0;
        size_t foundHere;
        while((foundHere = context.find(from, lookHere)) != string::npos)
        {
              context.replace(foundHere, from.size(), to);
              lookHere = foundHere + to.size();
        }
        return context;
    }
    Il n'y a plus qu'à transformer les tableaux en std::string ce qui est trivial.
    Du reste, pour lire le tableau de char d'une std::string, tu peux utiliser la méthode c_str(). Attention, si tu veux utiliser ailleurs ce tableau résultat, il faudra en faire une copie.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 5
    Par défaut
    Je ne suis pas sur d'avoir bien compris, pourrait tu commenter ces lignes de code? car la sa me dépasse.

  16. #16
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Si tu travaille de manière obligatoire sur des char* (ou des char[]), alors ce code devrait faire l'affaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    // remplace les chaines "from" par "to" dans "src", et stocke le résultat dans 
    // dst (dont la taille maximale est dstlen). Histoire de faire bien, si on a pas 
    // réussi à stocker le résultat dans dst, on renvoie -1
    int replace_in_string(const char* src, char* dst, unsigned int dstlen, const char* from, const char* to)
    {
      // on va commencer par récupérer les longueurs des chaines défniies
      unsigned int srclen = strlen(src);
      unsigned int fromlen = strlen(from);
      unsigned int tolen = strlen(to);
     
      // on garde le dernier caractère pour rajouter le '\0'
      --dstlen;
     
      // il y a deux étapes : en premier, il faut trouver les occurences 
      // de from dans src. C'est une recherche de chaine classique. Pour
      // s'en sortir, on maintient deux index : i est la position dans src, et
      // n est le nombre de caractères de from trouvés dans src. Un troisième
      // compteur nous indique la position courante dans dst, parce qu'elle n'est
      // pas nécessairement égale à i.
      unsigned int i = 0; // compteur sur src
      unsigned int j = 0; // compteur sur dst
      unsigned int n = 0; // compteur sur from
     
      for ( ; i<srclen && j<dstlen; ++i)
      {
        if (src[i] != from[n])
        {
          // si le caractère courant de src n'est pas le caractère courant de from
          // alors il faudra chercher à partir du premier caractère (et ajouter 
          // le caractère trouvé dans dst)
          dst[j++] = src[i];
          n = 0;
        }
        else
        {
          // le caractère courant de src est aussi celui de from : on est en passe
          // de trouver la chaine from dans src. En fait, la condition pour que from
          // ait été trouvé complètement, c'est que n soit égal à fromlen
          ++n;
          if (n == fromlen)
          {
            // c'est le cas ? Alors il faut copier le contenu de to dans dst, 
            // en prenant garde à ne pas dépasser au delà de la taille maximale
            // de dst
            for (unsigned int k=0; k<tolen && j<dstlen; ++k, ++j)
            {
              dst[i] = to[k];
            }
            // on reboot la recherche
            n = 0;
          }
        }
      }
      // on va pouvoir vérifier la condition d'erreur : si on a rempli dst à hauteur
      // de dstlen et que src n'a pas été pris en compte complètement, alors
      // c'est qu'il y a une erreur
      if (i < srclen && j == dstlen) return -1;
     
      // s'il n'y a pas eu d'erreur, alors on peut terminer : il faut rajouter le
      // \0 à la fin de dst. Fort heureusement, on a gardé la place plus tôt
      // avec un chouette effet de bord : dstlen étant plus court de 1 que la
      // longueur réelle de dst, et j ne pouvant être supérieur à cette valeur,
      // je peux directement adresser dst[j] sans risquer de problème. 
      dst[j] = '\0';
      return 0;
    }
    Voilà. J'ai essayer de mettre le maximum de commentaire. C'est presque du C, à à part quelques libertés (commentaires C++, et certaines déclarations de variables sont incompatibles avec du C).

    Si je n'ai pas fait d'erreur (et si j'en ai fait, et bien ça te fournira une bonne excuse pour bien rentrer dans le code), ça devrait permettre de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char dst[128];
    if (replace_in_string("Bonne année", dst, sizeof(dst), "nn", "ace"))
    {
      std::cout << dst << std::endl;
    }
    // écrit Boace aaceée.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Remplacer une chaîne de caractères dans une base de données
    Par Furius dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 27/11/2013, 21h06
  2. Remplacer une chaîne de caractère dans un gros fichier
    Par dosilbr dans le forum Autres Logiciels
    Réponses: 3
    Dernier message: 06/03/2007, 13h38
  3. [SQL] Remplacement de chaîne de caractères
    Par squal29 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 22/08/2006, 00h49
  4. Réponses: 8
    Dernier message: 15/07/2006, 18h59
  5. Remplacer une chaîne de caractères dans une base
    Par Furius dans le forum Requêtes
    Réponses: 4
    Dernier message: 19/10/2005, 23h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo