Réponses:
std::string
ne contient pas une telle fonction mais vous pouvez utiliser une replace
fonction autonome depuis l'en- algorithm
tête.
#include <algorithm>
#include <string>
void some_func() {
std::string s = "example string";
std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y'
}
std::string::replace()
au lieu de std::replace()
! 'x' ( char
) est implicitement casté en size_t
[valeur 120], ainsi la chaîne entière ou une partie de celle-ci sera remplie avec 120 copies de 'y'.
Je pensais que je jetterais aussi la solution boost :
#include <boost/algorithm/string/replace.hpp>
// in place
std::string in_place = "blah#blah";
boost::replace_all(in_place, "#", "@");
// copy
const std::string input = "blah#blah";
std::string output = boost::replace_all_copy(input, "#", "@");
-I
indicateurs pour votre compilateur afin qu'il trouve les bibliothèques Boost sur votre système. Vous devrez peut-être même l'installer d'abord.
La question est centrée sur le character
remplacement, mais, comme j'ai trouvé cette page très utile (surtout la remarque de Konrad ), je voudrais partager cette implémentation plus généralisée, qui permet de traiter substrings
également:
std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring 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
ÉDITER:
Ce qui précède peut être implémenté de manière plus appropriée, au cas où les performances vous intéressent, en ne retournant rien ( void
) et en effectuant les changements directement sur la chaîne str
donnée en argument, passée par adresse au lieu de 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::string &str, const std::string& from, const std::string& to)
{
// Same inner code...
// No return statement
}
J'espère que cela sera utile pour d'autres ...
from
chaîne est vide, sinon une boucle sans fin se produira.
Imaginez un gros objet binaire 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 aucun \ 0 octet.
Dans les cas où:
les solutions fournies ne peuvent pas être appliquées (car elles ne remplacent que des caractères uniques) ou ont un problème de performances, car elles appellent plusieurs fois string :: replace, 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 c'est OK de ce point de vue)
Celui-ci parcourt toutes les occurrences de la chaîne source et construit la nouvelle chaîne pièce par pièce une fois :
void replaceAll(std::string& source, const std::string& from, const std::string& to)
{
std::string newString;
newString.reserve(source.length()); // avoids a few memory allocations
std::string::size_type lastPos = 0;
std::string::size_type findPos;
while(std::string::npos != (findPos = source.find(from, lastPos)))
{
newString.append(source, lastPos, findPos - lastPos);
newString += to;
lastPos = findPos + from.length();
}
// Care for the rest after last occurrence
newString += source.substr(lastPos);
source.swap(newString);
}
Une simple recherche et remplacement pour un seul caractère aurait quelque chose comme:
s.replace(s.find("x"), 1, "y")
Pour ce faire, pour la chaîne entière, la chose la plus simple serait de boucler jusqu'à ce que vous s.find
commenciez à revenir npos
. Je suppose que vous pouvez également attraper range_error
pour quitter la boucle, mais c'est un peu moche.
{
personnage. Je ne sais pas ce qu'est une "double accolade". Vous avez peut-être un problème de police?
Si vous cherchez à remplacer plus d'un seul caractère, et que vous ne traitez qu'avec std::string
, cet extrait fonctionnerait, remplaçant sNeedle dans sHaystack par sReplace, et sNeedle et sReplace n'ont pas besoin d'être de la même taille. Cette routine utilise la boucle while pour remplacer toutes les occurrences, plutôt que la première trouvée de gauche à droite.
while(sHaystack.find(sNeedle) != std::string::npos) {
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}
find
appel deux fois. Pensez à faire de ce résultat une variable temporaire.
Comme l'a suggéré Kirill, utilisez la méthode replace ou parcourez la chaîne en remplaçant chaque caractère indépendamment.
Alternativement, vous pouvez utiliser la find
méthode ou find_first_of
selon ce que vous devez faire. Aucune de ces solutions ne fera l'affaire en une seule fois, mais avec quelques lignes de code supplémentaires, vous devriez les faire fonctionner pour vous. :-)
#include <iostream>
#include <string>
using namespace std;
// Replace function..
string replace(string word, string target, string replacement){
int len, loop=0;
string 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<<replace(word, "x", "y")<<endl;
return 0;
}
word
est long, il peut y avoir beaucoup de surcharge lors de l'appel de la fonction. Vous pouvez optimiser cela en passant word
, target
et replacement
comme références de const.
Et Abseil StrReplaceAll ? Depuis le fichier d'en-tête:
// This file defines `absl::StrReplaceAll()`, a general-purpose string
// replacement function designed for large, arbitrary text substitutions,
// especially on strings which you are receiving from some other system for
// further processing (e.g. processing regular expressions, escaping HTML
// entities, etc.). `StrReplaceAll` is designed to be efficient even when only
// one substitution is being performed, or when substitution is rare.
//
// If the string being modified is known at compile-time, and the substitutions
// vary, `absl::Substitute()` may be a better choice.
//
// Example:
//
// std::string html_escaped = absl::StrReplaceAll(user_input, {
// {"&", "&"},
// {"<", "<"},
// {">", ">"},
// {"\"", """},
// {"'", "'"}});
Vieille école :-)
std::string str = "H:/recursos/audio/youtube/libre/falta/";
for (int i = 0; i < str.size(); i++) {
if (str[i] == '/') {
str[i] = '\\';
}
}
std::cout << str;
Résultat:
H: \ recursos \ audio \ youtube \ libre \ falta \
Cela marche! J'ai utilisé quelque chose de similaire à cela 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 un caractère de conversion non valide.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count = 0; // for the number of occurences.
// final hold variable of corrected word up to the npos=j
string holdWord = "";
// a temp var in order to replace 0 to new npos
string holdTemp = "";
// a csv for a an entry in a book store
string 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 façon inhabituelle, j'utilise actuellement CentOS, donc ma version du compilateur est ci-dessous. La version C ++ (g ++), C ++ 98 par défaut:
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 êtes prêt à utiliser std::string
s, vous pouvez utiliser la fonction de cet exemple d'application strsub
telle quelle ou la mettre à jour si vous souhaitez qu'elle prenne un type ou un ensemble de paramètres différent pour atteindre à peu près le même objectif. Fondamentalement, il utilise les propriétés et fonctionnalités de std::string
pour effacer rapidement le jeu de caractères correspondant et insérer les caractères souhaités directement dans lestd::string
. Chaque fois qu'il effectue cette opération de remplacement, l'offset est mis à jour s'il peut toujours trouver les caractères correspondants à remplacer, et s'il ne peut plus rien remplacer, il renvoie la chaîne dans son état depuis la dernière mise à jour.
#include <iostream>
#include <string>
std::string strsub(std::string stringToModify,
std::string charsToReplace,
std::string replacementChars);
int main()
{
std::string 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 compter sur l'utilisation de std::string
s comme paramètres pour pouvoir passer des chaînes de style C à la place, vous pouvez voir l'exemple mis à jour ci-dessous:
#include <iostream>
#include <string>
std::string strsub(const char * stringToModify,
const char * charsToReplace,
const char * replacementChars,
uint64_t sizeOfCharsToReplace,
uint64_t sizeOfReplacementChars);
int main()
{
std::string 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 les situations simples, cela fonctionne assez bien sans utiliser d'autre bibliothèque que std :: string (qui est déjà utilisée).
Remplacez toutes les occurrences du caractère a par le caractère b dans some_string :
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 sont un problème, vous pouvez appliquer la technique mentionnée dans cette réponse: https://stackoverflow.com/a/29752943/3622300
voici une solution que j'ai roulée, dans un esprit DRI maximal. il recherchera sNeedle dans sHaystack et le remplacera par sReplace, nTimes si non 0, sinon toutes les occurrences de sNeedle. il ne cherchera pas à nouveau dans le texte remplacé.
std::string str_replace(
std::string sHaystack, std::string sNeedle, std::string sReplace,
size_t nTimes=0)
{
size_t found = 0, pos = 0, c = 0;
size_t len = sNeedle.size();
size_t replen = sReplace.size();
std::string input(sHaystack);
do {
found = input.find(sNeedle, pos);
if (found == std::string::npos) {
break;
}
input.replace(found, len, sReplace);
pos = found + replen;
++c;
} while(!nTimes || c < nTimes);
return input;
}
std::string
est un conteneur spécialement conçu pour fonctionner avec des séquences de caractères. lien