¿Cuál es la forma preferida de eliminar espacios de una cadena en C ++? Podría recorrer todos los personajes y construir una nueva cadena, pero ¿hay una mejor manera?
¿Cuál es la forma preferida de eliminar espacios de una cadena en C ++? Podría recorrer todos los personajes y construir una nueva cadena, pero ¿hay una mejor manera?
Respuestas:
Lo mejor que puede hacer es usar el algoritmo remove_if
y el espacio de emisión:
remove_if(str.begin(), str.end(), isspace);
Ahora el algoritmo en sí mismo no puede cambiar el contenedor (solo modificar los valores), por lo que realmente baraja los valores y devuelve un puntero a donde debería estar el final ahora. Entonces tenemos que llamar a string :: erase para modificar realmente la longitud del contenedor:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
También debemos tener en cuenta que remove_if hará como máximo una copia de los datos. Aquí hay una implementación de muestra:
template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
T dest = beg;
for (T itr = beg;itr != end; ++itr)
if (!pred(*itr))
*(dest++) = *itr;
return dest;
}
erase
después. Eso devolverá el resultado correcto.
isspace
es UB para todos los juegos de caracteres excepto el ASCII original de 7 bits. C99 §7.4 / 1. que no sorprende mí que ha sido upvoted por una suma de 71 votos por ahora, a pesar de ser muy mal consejo.
isspace
, para todos los caracteres no ASCII, con la opción predeterminada de firma en la práctica char
. Por lo tanto, tiene un comportamiento indefinido . Lo estoy repitiendo porque sospecho un intento deliberado de ahogar ese hecho en ruido.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
para que esto funcione.
De gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::isspace
es UB.
¿Puedes usar Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
erase_all(str, " ");
remove_if(str.begin(), str.end(), isspace);
que mencionó Matt Price. No se porque. En realidad, todas las cosas de impulso, que tienen alternativas STL, son más lentas que las correspondientes a gcc (todas las que probé). ¡Algunos de ellos son inmensamente más lentos! (hasta 5 veces en inserciones de mapas desordenados) Tal vez se deba a la memoria caché de la CPU del entorno compartido o algo similar.
Para recortar, use algoritmos de cadena de refuerzo :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Puede usar esta solución para eliminar un char:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Hola, puedes hacer algo así. Esta función elimina todos los espacios.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Hice otra función, que elimina todos los espacios innecesarios.
string delUnnecessary(string &str)
{
int size = str.length();
for(int j = 0; j<=size; j++)
{
for(int i = 0; i <=j; i++)
{
if(str[i] == ' ' && str[i+1] == ' ')
{
str.erase(str.begin() + i);
}
else if(str[0]== ' ')
{
str.erase(str.begin());
}
else if(str[i] == '\0' && str[i-1]== ' ')
{
str.erase(str.end() - 1);
}
}
}
return str;
}
string replaceinString(std::string str, std::string tofind, std::string toreplace)
{
size_t position = 0;
for ( position = str.find(tofind); position != std::string::npos; position = str.find(tofind,position) )
{
str.replace(position ,1, toreplace);
}
return(str);
}
úsalo:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Si desea hacer esto con una macro fácil, aquí hay una:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Esto supone que lo has hecho, #include <string>
por supuesto.
Llámalo así:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
Usé el siguiente trabajo durante mucho tiempo, no estoy seguro de su complejidad.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
cuando quieres eliminar el personaje ' '
y algunos, por ejemplo, -
usan
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
Del mismo modo, solo aumente el ||
número de caracteres que desea eliminar no es 1
pero como lo mencionaron otros, el idioma de borrar borrado también parece estar bien.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
Este código básicamente toma una cadena e itera a través de cada carácter que contiene. Luego verifica si esa cadena es un espacio en blanco, si no lo es, el carácter se agrega a una nueva cadena.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Referencia tomada de este foro.
En C ++ 20 puede usar la función gratuita std :: erase
std::string str = " Hello World !";
std::erase(str, ' ');
Ejemplo completo:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
Yo imprimo | para que sea obvio que también se elimina el espacio al principio.
nota: esto elimina solo el espacio, no todos los demás caracteres posibles que pueden considerarse espacios en blanco, consulte https://en.cppreference.com/w/cpp/string/byte/isspace
Elimina todos los caracteres de espacio en blanco , como tabulaciones y saltos de línea (C ++ 11):
string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");
string str = "2C F4 32 3C B9 DE";
str.erase(remove(str.begin(),str.end(),' '),str.end());
cout << str << endl;
salida: 2CF4323CB9DE
string removespace(string str)
{
int m = str.length();
int i=0;
while(i<m)
{
while(str[i] == 32)
str.erase(i,1);
i++;
}
}
length()
devuelve un size_t
, no un int
. erase()
toma un size_type
, no un int
. La función probablemente fallará si se encuentran dos espacios consecutivos ya que el índice siempre se incrementa. Si se elimina un espacio, el bucle leerá más allá de los límites de la cadena. Probablemente debería eliminar esta respuesta, ya que necesita mucha ayuda.
Me temo que es la mejor solución que se me ocurre. Pero puede usar reserve () para preasignar la memoria mínima requerida de antemano para acelerar un poco las cosas. Terminará con una nueva cadena que probablemente será más corta pero que ocupará la misma cantidad de memoria, pero evitará reasignaciones.
EDITAR: Dependiendo de su situación, esto puede generar menos gastos generales que los personajes confusos.
Debe probar diferentes enfoques y ver qué es lo mejor para usted: es posible que no tenga ningún problema de rendimiento.