c++ - una - replace c# varios caracteres
¿Cómo reemplazar todas las apariciones de un carácter en una cadena? (12)
¡Esto funciona! Utilicé algo similar a esto para una aplicación de librería, donde el inventario se almacenó en un CSV (como un archivo .dat). Pero en el caso de un solo char, lo que significa que el sustituto es solo un solo char, por ejemplo, ''|'', debe estar entre comillas dobles "|" con el fin de no lanzar una conversión inválida 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
No estoy acostumbrado a usar CentOS actualmente, por lo que la versión de mi compilador se encuentra a continuación. La versión de C ++ (g ++), C ++ 98 por defecto:
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.
¿Cuál es la forma efectiva de reemplazar todas las apariciones de un personaje con otro carácter en std::string
?
Como sugirió Kirill, use el método de reemplazo o repita en iteración a lo largo de la cadena reemplazando cada carácter de forma independiente.
Alternativamente, puede usar el método de find
o find_first_of
dependiendo de lo que necesita hacer. Ninguna de estas soluciones hará el trabajo de una sola vez, pero con unas pocas líneas de código adicionales, debe hacer que funcionen para usted. :-)
Imagine un blob binario grande donde todos los 0x00 bytes serán reemplazados por "/ 1 / x30" y todos los 0x01 bytes por "/ 1 / x31" porque el protocolo de transporte no permite / 0-bytes.
En los casos en que:
- la cadena de reemplazo y la cadena a reemplazar tienen longitudes diferentes,
- hay muchas apariciones de la cadena reemplazada dentro de la cadena de origen y
- la cadena fuente es grande,
las soluciones proporcionadas no se pueden aplicar (porque reemplazan solo los caracteres individuales) o tienen un problema de rendimiento, ya que llamarían cadena :: reemplazar varias veces, lo que genera copias del tamaño del blob una y otra vez. (No conozco la solución de impulso, tal vez esté bien desde esa perspectiva)
Éste recorre todas las apariciones en la cadena de origen y crea una vez por partes la nueva cadena:
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);
}
La pregunta se centra en el reemplazo de character
, pero, como esta página me pareció muy útil (especialmente el comentario de Konrad ), me gustaría compartir esta implementación más generalizada, que también permite tratar las 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;
}
Uso:
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;
Salidas:
Number_Of_Beans
XXjXugtXty
hhjhugthty
EDITAR:
Lo anterior se puede implementar de una manera más adecuada, en caso de que el rendimiento sea de su interés, no devuelva nada ( void
) y realice los cambios directamente en la cadena de caracteres dada como argumento, que se transmite por dirección en lugar de por valor . Esto evitaría una copia inútil y costosa de la cadena original, mientras se devuelve el resultado. Su llamada, entonces ...
Código:
static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to)
{
// Same inner code...
// No return statement
}
Espero que esto sea de ayuda para algunos otros ...
Para situaciones simples, esto funciona bastante bien sin usar ninguna otra biblioteca y luego std :: string (que ya está en uso).
Reemplace todas las apariciones del carácter a con el carácter b en 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 cadena es grande o si hay varias llamadas para reemplazar es un problema, puede aplicar la técnica mencionada en esta respuesta: https://.com/a/29752943/3622300
Pensé que también lanzaría la solución de refuerzo :
#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, "#", "@");
Si está buscando reemplazar más de un solo carácter, y está tratando solo con std::string
, entonces este fragmento de código funcionaría, reemplazando sNeedle en sHaystack con sReplace, y sNeedle y sReplace no necesitan ser del mismo tamaño. Esta rutina usa el bucle while para reemplazar todas las ocurrencias, en lugar de la primera que se encuentra de izquierda a derecha.
while(sHaystack.find(sNeedle) != std::string::npos) {
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}
Si está dispuesto a usar std::string
s, puede usar la función strsub
esta aplicación de strsub
tal como está, o actualizarla si desea que tome un tipo diferente o un conjunto de parámetros para lograr aproximadamente el mismo objetivo. Básicamente, utiliza las propiedades y funcionalidades de std::string
para borrar rápidamente el conjunto de caracteres coincidentes e insertar los caracteres deseados directamente dentro de std::string
. Cada vez que realiza esta operación de reemplazo, la compensación se actualiza si aún puede encontrar los caracteres que se deben reemplazar y, si no se puede reemplazar, devuelve la cadena en su estado desde la última actualización.
#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 no desea confiar en el uso de std::string
s como sus parámetros para que pueda pasar cadenas de estilo C en su lugar, puede ver el ejemplo actualizado a continuación:
#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;
}
Un simple hallazgo y reemplazo para un solo personaje sería algo como:
s.replace(s.find("x"), 1, "y")
Para hacer esto por toda la cadena, lo más fácil sería hacer un bucle hasta que su s.find
empiece a devolver npos
. Supongo que también podrías atrapar a range_error
para salir del bucle, pero eso es un poco feo.
Vieja escuela :-)
string pth = "H:/recursos/audio/youtube/libre/falta/";
for(int i=0 ;i<=pth.size(); i++)
if(pth[i]==''/'')
pth[i]=''//';
cout<<pth;
Resultado: "H: / recursos / audio / youtube / libre / falta /";
std::string
no contiene dicha función, pero podría usar la función de replace
independiente del encabezado del algorithm
.
#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''
}
#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;
}