¿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?
222
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ácticachar
. Por lo tanto, tiene un comportamiento indefinido . Lo estoy repitiendo porque sospecho un intento deliberado de ahogar ese hecho en ruido.fuente
<algorithm>
para que esto funcione.De gamedev
fuente
::isspace
es UB.¿Puedes usar Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
fuente
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 :
fuente
Puede usar esta solución para eliminar un char:
fuente
Hola, puedes hacer algo así. Esta función elimina todos los espacios.
Hice otra función, que elimina todos los espacios innecesarios.
fuente
úsalo:
fuente
Si desea hacer esto con una macro fácil, aquí hay una:
Esto supone que lo has hecho,
#include <string>
por supuesto.Llámalo así:
fuente
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,-
usans.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 1pero como lo mencionaron otros, el idioma de borrar borrado también parece estar bien.
fuente
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.
fuente
Fuente:
Referencia tomada de este foro.
fuente
En C ++ 20 puede usar la función gratuita std :: erase
Ejemplo completo:
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
fuente
Elimina todos los caracteres de espacio en blanco , como tabulaciones y saltos de línea (C ++ 11):
fuente
salida: 2CF4323CB9DE
fuente
fuente
length()
devuelve unsize_t
, no unint
.erase()
toma unsize_type
, no unint
. 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.
fuente