Antworten:
std::string
enthält keine solche Funktion, aber Sie können die eigenständige replace
Funktion aus dem algorithm
Header verwenden.
#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()
statt std::replace()
! 'x' ( char
) wird implizit in size_t
[Wert 120] umgewandelt, sodass die gesamte Zeichenfolge oder ein Teil davon mit 120 Kopien von 'y' gefüllt wird.
Ich dachte, ich würde auch die Boost-Lösung einwerfen:
#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
Flags für Ihren Compiler, damit er die Boost-Bibliotheken auf Ihrem System findet. Vielleicht müssen Sie es zuerst installieren.
Die Frage konzentriert sich auf das character
Ersetzen, aber da ich diese Seite sehr nützlich fand (insbesondere Konrads Bemerkung), möchte ich diese allgemeinere Implementierung teilen, die auch Folgendes ermöglicht substrings
:
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;
}
Verwendungszweck:
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;
Ausgänge:
Number_Of_Beans
XXjXugtXty
hhjhugthty
BEARBEITEN:
Das Obige kann in geeigneterer Weise implementiert werden, falls die Leistung von Belang ist, indem nichts zurückgegeben wird ( void
) und die Änderungen direkt an der str
als Argument angegebenen Zeichenfolge ausgeführt werden, die als Adresse statt als Wert übergeben wird . Dies würde eine nutzlose und kostspielige Kopie der Originalzeichenfolge vermeiden und gleichzeitig das Ergebnis zurückgeben. Ihr Anruf dann ...
Code:
static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to)
{
// Same inner code...
// No return statement
}
Hoffe, dass dies für einige andere hilfreich sein wird ...
from
Zeichenfolge leer ist, da sonst eine Endlosschleife auftritt.
Stellen Sie sich einen großen binären Blob vor, bei dem alle 0x00 Bytes durch "\ 1 \ x30" und alle 0x01 Bytes durch "\ 1 \ x31" ersetzt werden sollen, da das Transportprotokoll keine \ 0 Bytes zulässt.
In Fällen, in denen:
Die bereitgestellten Lösungen können nicht angewendet werden (da sie nur einzelne Zeichen ersetzen) oder haben ein Leistungsproblem, da sie string :: replace mehrmals aufrufen würden, wodurch immer wieder Kopien der Größe des Blobs generiert werden. (Ich kenne die Boost-Lösung nicht, vielleicht ist es aus dieser Perspektive in Ordnung)
Dieser geht alle Vorkommen in der Quellzeichenfolge entlang und erstellt die neue Zeichenfolge Stück für Stück einmal :
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);
}
Ein einfaches Suchen und Ersetzen eines einzelnen Zeichens würde ungefähr so aussehen:
s.replace(s.find("x"), 1, "y")
Um dies für die gesamte Zeichenfolge zu tun, ist es einfach, eine Schleife zu erstellen, bis Sie s.find
zurückkehren npos
. Ich nehme an, Sie könnten auch fangen range_error
, um die Schleife zu verlassen, aber das ist irgendwie hässlich.
{
Charakter. Ich weiß nicht, was eine "Doppelklammer" ist. Vielleicht haben Sie ein Schriftproblem?
Wenn Sie mehr als ein einzelnes Zeichen std::string
ersetzen möchten und nur damit arbeiten, funktioniert dieses Snippet und ersetzt sNeedle in sHaystack durch sReplace, und sNeedle und sReplace müssen nicht dieselbe Größe haben. Diese Routine verwendet die while-Schleife, um alle Vorkommen zu ersetzen, und nicht nur die erste, die von links nach rechts gefunden wurde.
while(sHaystack.find(sNeedle) != std::string::npos) {
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}
find
zweimal einen Anruf. Erwägen Sie, dieses Ergebnis zu einer temporären Variablen zu machen.
Verwenden Sie, wie Kirill vorgeschlagen hat, entweder die Ersetzungsmethode oder iterieren Sie entlang der Zeichenfolge, um jedes Zeichen unabhängig voneinander zu ersetzen.
Alternativ können Sie die find
Methode verwenden oder find_first_of
je nachdem, was Sie tun müssen. Keine dieser Lösungen erledigt die Aufgabe auf einmal, aber mit ein paar zusätzlichen Codezeilen sollten Sie sie für Sie arbeiten lassen. :-)
#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
es lang ist, kann es beim Aufrufen der Funktion zu einem hohen Overhead kommen. Sie können diese optimieren , indem man word
, target
und replacement
als const Verweise.
Was ist mit Abseil StrReplaceAll ? Aus der Header-Datei:
// 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, {
// {"&", "&"},
// {"<", "<"},
// {">", ">"},
// {"\"", """},
// {"'", "'"}});
Alte Schule :-)
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;
Ergebnis:
H: \ recursos \ audio \ youtube \ libre \ falta \
Das funktioniert! Ich habe etwas Ähnliches für eine Buchhandlungs-App verwendet, in der das Inventar in einer CSV (wie einer .dat-Datei) gespeichert wurde. Im Fall eines einzelnen Zeichens, dh der Ersetzer ist nur ein einzelnes Zeichen, z. B. '|', muss es in doppelten Anführungszeichen "|" stehen. um keine ungültige Konvertierung zu werfen const char.
#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
Normalerweise verwende ich derzeit CentOS, daher ist meine Compilerversion unten aufgeführt. Die C ++ - Version (g ++), C ++ 98 Standard:
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.
Wenn Sie bereit sind, std::string
s zu verwenden , können Sie die strsub
Funktion dieser Beispiel-App unverändert verwenden oder aktualisieren, wenn Sie möchten, dass ein anderer Typ oder ein anderer Parametersatz verwendet wird, um ungefähr dasselbe Ziel zu erreichen. Grundsätzlich werden die Eigenschaften und Funktionen von verwendet std::string
, um den übereinstimmenden Zeichensatz schnell zu löschen und die gewünschten Zeichen direkt in das Zeichen einzufügen std::string
. Jedes Mal, wenn dieser Ersetzungsvorgang ausgeführt wird, wird der Offset aktualisiert, wenn immer noch passende Zeichen zum Ersetzen gefunden werden können. Wenn er nicht ersetzt werden kann, gibt er die Zeichenfolge in ihrem Zustand vom letzten Update zurück.
#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;
}
Wenn Sie sich nicht auf die Verwendung von std::string
s als Parameter verlassen möchten, um stattdessen Zeichenfolgen im C-Stil zu übergeben, sehen Sie das aktualisierte Beispiel unten:
#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;
}
In einfachen Situationen funktioniert dies ziemlich gut, ohne eine andere Bibliothek als std :: string (die bereits verwendet wird) zu verwenden.
Ersetzen Sie alle Vorkommen von Zeichen a durch Zeichen b in some_string :
for (size_t i = 0; i < some_string.size(); ++i) {
if (some_string[i] == 'a') {
some_string.replace(i, 1, "b");
}
}
Wenn die Zeichenfolge groß ist oder mehrere zu ersetzende Aufrufe ein Problem darstellen, können Sie die in dieser Antwort erwähnte Technik anwenden: https://stackoverflow.com/a/29752943/3622300
Hier ist eine Lösung, die ich in einem maximalen DRI-Geist entwickelt habe. es sucht sNeedle in sHaystack und ersetzt es durch sReplace, nTimes wenn nicht 0, sonst alle sNeedle-Vorkommen. Der ersetzte Text wird nicht erneut gesucht.
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
ist ein Container, der speziell für die Arbeit mit Zeichenfolgen entwickelt wurde. Link