Comment remplacer toutes les occurrences d’un caractère dans une chaîne?

Quel est le moyen efficace de remplacer toutes les occurrences d’un personnage par un autre caractère dans std::ssortingng ?

std::ssortingng ne contient pas une telle fonction mais vous pouvez utiliser la fonction de replace autonome de l’ algorithm tête d’ algorithm .

 #include  #include  void some_func() { std::ssortingng s = "example ssortingng"; std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y' } 

Je pensais que je lancerais également la solution boost :

 #include  // in place std::ssortingng in_place = "blah#blah"; boost::replace_all(in_place, "#", "@"); // copy const std::ssortingng input = "blah#blah"; std::ssortingng output = boost::replace_all_copy(input, "#", "@"); 

La question est centrée sur le remplacement de character , mais comme j’ai trouvé cette page très utile (en particulier la remarque de Konrad ), j’aimerais partager cette implémentation plus généralisée, qui permet également de traiter des subssortingngs :

 std::ssortingng ReplaceAll(std::ssortingng str, const std::ssortingng& from, const std::ssortingng& to) { size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::ssortingng::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); // Handles case where 'to' is a subssortingng of 'from' } return str; } 

Usage:

 std::cout << ReplaceAll(string("Number Of Beans"), std::string(" "), std::string("_")) << std::endl; std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("X")) << std::endl; std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("h")) << std::endl; 

Les sorties:

Number_Of_Beans

XXjXugtXty

hhjhugthty


MODIFIER:

Ce qui précède peut être implémenté de manière plus appropriée, dans le cas où les performances vous préoccupent, en ne retournant rien ( void ) et en effectuant les modifications directement sur la chaîne str donnée en argument, passée par adresse et non par valeur . Cela éviterait une copie inutile et coûteuse de la chaîne d'origine, tout en renvoyant le résultat. Votre appel, alors ...

Code:

 static inline void ReplaceAll2(std::ssortingng &str, const std::ssortingng& from, const std::ssortingng& to) { // Same inner code... // No return statement } 

J'espère que cela sera utile pour d'autres ...

Imaginez un gros blob binary où tous les octets 0x00 doivent être remplacés par “\ 1 \ x30” et tous les octets 0x01 par “\ 1 \ x31” car le protocole de transport n’autorise pas \ 0-octets.

Dans les cas où:

  • le remplacement et la chaîne remplacée ont des longueurs différentes,
  • il y a beaucoup d’occurrences de la chaîne à remplacer dans la chaîne source et
  • la chaîne source est grande,

Les solutions fournies ne peuvent pas être appliquées (car elles ne remplacent que des caractères uniques) ou présentent un problème de performances, car elles appellent ssortingng :: replace plusieurs fois, ce qui génère des copies de la taille du blob encore et encore. (Je ne connais pas la solution boost, peut-être que ça va de ce sharepoint vue)

Celui-ci parcourt toutes les occurrences de la chaîne source et construit la nouvelle chaîne pièce par pièce:

 void replaceAll(std::ssortingng& source, const std::ssortingng& from, const std::ssortingng& to) { std::ssortingng newSsortingng; newSsortingng.reserve(source.length()); // avoids a few memory allocations std::ssortingng::size_type lastPos = 0; std::ssortingng::size_type findPos; while(std::ssortingng::npos != (findPos = source.find(from, lastPos))) { newSsortingng.append(source, lastPos, findPos - lastPos); newSsortingng += to; lastPos = findPos + from.length(); } // Care for the rest after last occurrence newSsortingng += source.substr(lastPos); source.swap(newSsortingng); } 

Une simple recherche et remplacement pour un seul caractère irait quelque chose comme:

s.replace(s.find("x"), 1, "y")

Pour faire cela pour toute la chaîne, la chose facile à faire serait de boucler jusqu’à ce que votre s.find commence à renvoyer npos . Je suppose que vous pouvez également intercepter range_error pour sortir de la boucle, mais c’est plutôt moche.

Comme Kirill l’a suggéré, utilisez la méthode replace ou itérez le long de la chaîne en remplaçant chaque caractère indépendamment.

Vous pouvez également utiliser la méthode find ou find_first_of fonction de ce que vous devez faire. Aucune de ces solutions ne fera le travail en une fois, mais avec quelques lignes de code supplémentaires, vous devriez les faire fonctionner pour vous. 🙂

Si vous cherchez à remplacer plus d’un caractère et que vous ne travaillez qu’avec std::ssortingng , cet extrait fonctionnera, en remplaçant sNeedle dans sHaystack par sReplace, et il n’est pas nécessaire que sNeedle et sReplace aient la même taille. Cette routine utilise la boucle while pour remplacer toutes les occurrences, et pas seulement la première trouvée de gauche à droite.

 while(sHaystack.find(sNeedle) != std::ssortingng::npos) { sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace); } 
 #include  #include  using namespace std; // Replace function.. ssortingng replace(ssortingng word, ssortingng target, ssortingng replacement){ int len, loop=0; ssortingng nword="", let; len=word.length(); len--; while(loop<=len){ let=word.substr(loop, 1); if(let==target){ nword=nword+replacement; }else{ nword=nword+let; } loop++; } return nword; } //Main.. int main() { string word; cout<<"Enter Word: "; cin>>word; cout< 

Cela marche! J’ai utilisé quelque chose de similaire pour une application de librairie, où l’inventaire était stocké dans un fichier CSV (comme un fichier .dat). Mais dans le cas d’un seul caractère, ce qui signifie que le remplaçant n’est qu’un seul caractère, par exemple “|”, il doit être entre guillemets “|” afin de ne pas lancer une const de conversion invalide.

 #include  #include  using namespace std; int main() { int count = 0; // for the number of occurences. // final hold variable of corrected word up to the npos=j ssortingng holdWord = ""; // a temp var in order to replace 0 to new npos ssortingng holdTemp = ""; // a csv for a an entry in a book store ssortingng holdLetter = "Big Java 7th Ed,Horstman,978-1118431115,99.85"; // j = npos for (int j = 0; j < holdLetter.length(); j++) { if (holdLetter[j] == ',') { if ( count == 0 ) { holdWord = holdLetter.replace(j, 1, " | "); } else { string holdTemp1 = holdLetter.replace(j, 1, " | "); // since replacement is three positions in length, // must replace new replacement's 0 to npos-3, with // the 0 to npos - 3 of the old replacement holdTemp = holdTemp1.replace(0, j-3, holdWord, 0, j-3); holdWord = ""; holdWord = holdTemp; } holdTemp = ""; count++; } } cout << holdWord << endl; return 0; } // result: Big Java 7th Ed | Horstman | 978-1118431115 | 99.85 

De manière inhabituelle, j'utilise actuellement CentOS, donc ma version du compilateur est ci-dessous. La version C ++ (g ++), par défaut C ++ 98:

 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Si vous souhaitez utiliser std::ssortingng s, vous pouvez utiliser la fonction strsub cette exemple-app ou la mettre à jour si vous souhaitez utiliser un type ou un ensemble de parameters différent pour atteindre à peu près le même objective. Fondamentalement, il utilise les propriétés et fonctionnalités de std::ssortingng pour effacer rapidement l’ensemble de caractères correspondant et insérer les caractères souhaités directement dans la std::ssortingng . Chaque fois qu’il effectue cette opération de remplacement, l’offset est mis à jour s’il peut toujours trouver des caractères correspondants à remplacer, et s’il ne peut pas le remplacer, il renvoie la chaîne dans son état depuis la dernière mise à jour.

 #include  #include  std::ssortingng strsub(std::ssortingng ssortingngToModify, std::ssortingng charsToReplace, std::ssortingng replacementChars); int main() { std::ssortingng silly_typos = "annoiiyyyng syyyllii tiipos."; std::cout << "Look at these " << silly_typos << std::endl; silly_typos = strsub(silly_typos, "yyy", "i"); std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl; silly_typos = strsub(silly_typos, "ii", "y"); std::cout << "There, no more " << silly_typos << std::endl; return 0; } std::string strsub(std::string stringToModify, std::string charsToReplace, std::string replacementChars) { std::string this_string = stringToModify; std::size_t this_occurrence = this_string.find(charsToReplace); while (this_occurrence != std::string::npos) { this_string.erase(this_occurrence, charsToReplace.size()); this_string.insert(this_occurrence, replacementChars); this_occurrence = this_string.find(charsToReplace, this_occurrence + replacementChars.size()); } return this_string; } 

Si vous ne voulez pas utiliser std::ssortingng s comme parameters pour pouvoir passer des chaînes de style C à la place, vous pouvez voir l'exemple mis à jour ci-dessous:

 #include  #include  std::ssortingng strsub(const char * ssortingngToModify, const char * charsToReplace, const char * replacementChars, uint64_t sizeOfCharsToReplace, uint64_t sizeOfReplacementChars); int main() { std::ssortingng silly_typos = "annoiiyyyng syyyllii tiipos."; std::cout << "Look at these " << silly_typos << std::endl; silly_typos = strsub(silly_typos.c_str(), "yyy", "i", 3, 1); std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl; silly_typos = strsub(silly_typos.c_str(), "ii", "y", 2, 1); std::cout << "There, no more " << silly_typos << std::endl; return 0; } std::string strsub(const char * stringToModify, const char * charsToReplace, const char * replacementChars, uint64_t sizeOfCharsToReplace, uint64_t sizeOfReplacementChars) { std::string this_string = stringToModify; std::size_t this_occurrence = this_string.find(charsToReplace); while (this_occurrence != std::string::npos) { this_string.erase(this_occurrence, sizeOfCharsToReplace); this_string.insert(this_occurrence, replacementChars); this_occurrence = this_string.find(charsToReplace, this_occurrence + sizeOfReplacementChars); } return this_string; } 

Pour des situations simples, cela fonctionne très bien sans utiliser aucune autre bibliothèque que std :: ssortingng (qui est déjà utilisée).

Remplace toutes les occurrences du caractère a par le caractère b dans some_ssortingng :

 for (size_t i = 0; i < some_string.size(); ++i) { if (some_string[i] == 'a') { some_string.replace(i, 1, "b"); } } 

Si la chaîne est volumineuse ou si plusieurs appels à remplacer posent problème, vous pouvez appliquer la technique mentionnée dans cette réponse: https://stackoverflow.com/a/29752943/3622300

Vieille école 🙂

  ssortingng pth = "H:/recursos/audio/youtube/libre/falta/"; for(int i=0 ;i<=pth.size(); i++) if(pth[i]=='/') pth[i]='\\'; cout< 

Résultat: "H: \ recursos \ audio \ youtube \ libre \ falta \";