¿Cuál es la mejor manera de reemplazar caracteres en una cadena?C++ character replace
Específicamente:
"This,Is A|Test" ----> "This_Is_A_Test"
quiero reemplazar todas las comas, espacios, y "|" con guiones bajos.
(tengo acceso a Boost.)
¿Cuál es la mejor manera de reemplazar caracteres en una cadena?C++ character replace
Específicamente:
"This,Is A|Test" ----> "This_Is_A_Test"
quiero reemplazar todas las comas, espacios, y "|" con guiones bajos.
(tengo acceso a Boost.)
Como las demás respuestas indicadas, puede utilizar los diversos métodos replace
. Sin embargo, estos enfoques tienen la desventaja de escanear la cadena varias veces (una vez para cada personaje). Yo recomendaría rodar su propio método de sustituir, si se preocupan por la velocidad:
void beautify(std::string &s) {
int i;
for (i = 0; i < s.length(); ++i) {
switch (s[i]) {
case ' ':
case ',':
case '|':
s[i] = '_';
}
}
}
La Biblioteca C++ Estándar tiene acceso a estas funciones, así, sin necesidad de impulso. Consulte el replace C++ Reference. Es esta la mejor manera ? Supongo que eso depende de la discusión. Para reemplazar caracteres múltiples/diferentes, es posible que deba llamar a reemplazar más de una vez.
#include <string>
string& replace(size_type index, size_type num, const string& str);
string& replace(size_type index1, size_type num1, const string& str, size_type index2, size_type num2);
string& replace(size_type index, size_type num, const Char* str);
string& replace(size_type index, size_type num1, const Char* str, size_type num2);
string& replace(size_type index, size_type num1, size_type num2, Char ch);
string& replace(iterator start, iterator end, const string& str);
string& replace(iterator start, iterator end, const Char* str);
string& replace(iterator start, iterator end, const Char* str, size_type num);
string& replace(iterator start, iterator end, size_type num, Char ch);
string& replace(iterator start, iterator end, input_iterator start2, input_iterator end2);
// replacing in a string
#include <iostream>
#include <string>
using namespace std;
int main()
{
string base="this is a test string.";
string str2="n example";
string str3="sample phrase";
string str4="useful.";
// function versions used in the same order as described above:
// Using positions: *123456789*12345
string str=base; // "this is a test string."
str.replace(9,5,str2); // "this is an example string."
str.replace(19,6,str3,7,6); // "this is an example phrase."
str.replace(8,10,"just all",6); // "this is just a phrase."
str.replace(8,6,"a short"); // "this is a short phrase."
str.replace(22,1,3,'!'); // "this is a short phrase!!!"
// Using iterators: *123456789*
string::iterator it = str.begin(); //^
str.replace(it,str.end()-3,str3); // "sample phrase!!!"
str.replace(it,it+6,"replace it",7); // "replace phrase!!!"
it+=8; // ^
str.replace(it,it+6,"is cool"); // "replace is cool!!!"
str.replace(it+4,str.end()-4,4,'o'); // "replace is cooool!!!"
it+=3; // ^
str.replace(it,str.end(),str4.begin(),str4.end());
// "replace is useful."
cout << str << endl;
return 0;
}
El método de reemplazo simplemente reemplaza un carácter (rango), no todas las apariciones de algo, así que diría que de hecho no es muy útil para esta tarea :) – UncleBens
Roger. Es por eso que dije que necesita ser ejecutado más de una vez. Si es la mejor metodología, depende del desarrollador –
En realidad, podría estar haciendo que el agua esté más embarrada. 'string :: replace' es para reemplazar un solo rango con otra cadena (o carácter (s)). OP desea reemplazar solo caracteres individuales, por lo tanto, en lugar del método de reemplazo de peso pesado, podría haber apuntado al operador [], lo que le permite "reemplazar" el valor de los caracteres individuales. – UncleBens
EDIT: ComoSpace_C0wb0y dicho, replace_if
es definitivamente mejor. Aquí hay un código de ejemplo simpler:
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
bool isBad(char c)
{
const string bad_chars = "|, ";
return (bad_chars.find(c) != string::npos);
}
int main()
{
string str = "This,Is A|Test";
// Replace!
replace_if(str.begin(),str.end(),isBad,'_');
cout<<str<<endl;
return 0;
}
vieja respuesta:
Uso std::replace con std::find_first_of
Usted podría utilizar el TEL-Algoritmo replace_if.
boost :: replace_all (s, viejo, nuevo);
estaba escribiendo esto, cuando Space_C0wb0y publicó su respuesta, que es la respuesta correcta para su pregunta. Esto es un poco más complicado, pero maneja más reemplazos posibles.
(lo siento, no compilado/prueba)
class MyReplacer
{
friend std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl);
public:
MyReplacer(char c) : ch(c) {}
private:
char ch;
};
std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl)
{
switch (Repl.ch)
{
case '|':
case ' ':
case ',': os << '_'; break;
default: os << Repl.ch;
}
return os;
}
std::ostringstream oss;
std::copy(str.begin(), str.end(), std::ostream_iterator<MyReplacer>(oss));
std::string result = oss.str();
podría utilizar el algoritmo estándar replace_if
, excepto el predicado es bastante complicado (que se expresa en línea con C++ estándar actual y sin lambda).
Usted puede escribir su propia, o utilizar is_any_of
de algoritmos de cuerda de impulso, por lo que:
#include <algorithm>
#include <string>
#include <boost/algorithm/string/classification.hpp>
#include <iostream>
int main()
{
std::string s("This,Is A|Test");
std::replace_if(s.begin(), s.end(), boost::is_any_of(", |"), '_');
std::cout << s << '\n';
}
¿Es esta una cadena de clase std :: string, o una matriz de tipo char con un terminador '\ 0' ? –
es std :: string – tinkertime
Creo que las diversas respuestas de replace_if, p. UncleBens, son buenos. Sin embargo, un comentario general: si está reemplazando personajes para obtener algo que sea seguro para su uso, p. como nombre de archivo, debe enumerar los caracteres permitidos y reemplazar todo lo demás, en lugar de al revés. De esa forma no te sorprenderá ninguna entrada extraña en la que no hayas pensado. –