2008-09-17 44 views

Respuesta

204

Lo mejor que puede hacer es utilizar el algoritmo remove_if y isspace:

remove_if(str.begin(), str.end(), isspace); 

Ahora el algoritmo en sí no puede cambiar el contenedor (sólo modificar los valores), por lo que en realidad baraja los valores alrededor y devuelve un puntero hacia donde debe estar el final ahora. Así que tenemos que llamar a string :: Borrar para modificar realmente la longitud del contenedor:

str.erase(remove_if(str.begin(), str.end(), isspace), str.end()); 

También debemos señalar que remove_if hará como máximo una copia de los datos. Aquí hay una implementación de ejemplo:

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; 
} 
+40

Debido a que 'isspace' tiene sobrecargas, es probable que necesite calificar el código genérico para usar :: isspace (la implementación C que no toma una configuración regional) o ser recibido con errores crípticos de creación de instancias de plantilla. – Bklyn

+4

Todos - tenga cuidado con el método anterior (Las dos líneas simples, no la versión con plantilla, aunque puede tener el mismo problema). Lo usé en un proyecto sin darme cuenta de que no siempre es correcto. Por ejemplo, si le pasa la cadena "1 + 1", devuelve "1 + 11". Cambié al método de @rupello a continuación y funcionó bien para este caso. Feliz codificación! – JoeB

+5

@Joe La respuesta menciona explícitamente que debe llamar a 'borrar' después. Eso devolverá el resultado correcto. –

31

De gamedev

string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end()); 
+16

Esto no se compilará en implementaciones que se ajusten a las normas debido a las sobrecargas de std :: isspace que toman localizaciones. Tendrá que usar :: isspace o realizar algunas maquinaciones ilegibles con std :: bind2nd. ¿No es hermoso el código genérico? – Bklyn

67
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' '); 
str.erase(end_pos, str.end()); 
+23

Mi voto positivo para el idioma canónico borrar/eliminar. Se puede hacer en un trazador: str.erase (std :: remove (str.begin(), str.end(), ''), str.end()); – Bklyn

+1

Nota: Debe incluir '' para que esto funcione. – Tara

-2

Me temo que es la mejor solución que se me ocurre. Pero puede usar reserve() para preasignar la memoria mínima requerida por adelantado 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á las reasignaciones.

EDITAR: Dependiendo de su situación, esto puede incurrir en menos gastos generales que los caracteres que se mezclan.

Debe probar diferentes enfoques y ver qué es lo mejor para usted: es posible que no tenga ningún problema de rendimiento.

+0

remove_if realiza como máximo una copia de cada valor. Entonces realmente no hay mucho sobrecarga relativa a lo que se necesita hacer. –

26

¿Se puede usar Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573

erase_all(str, " "); 
+1

Es más lento que el 'remove_if (str.begin(), str.end(), isspace);' que mencionó Matt Price. No sé por qué. En realidad, todas las cosas de impulso, que tienen alternativas de STL, son más lentas que las gcc correspondientes (todas las que probé). ¡Algunos de ellos son inmensamente más lentos! (hasta 5 veces en inserciones de mapa no ordenado) Tal vez sea debido a la memoria caché de la CPU del entorno compartido o algo así. – Etherealone

11

Para recortar, utilice boost string algorithms:

#include <boost/algorithm/string.hpp> 

using namespace std; 
using namespace boost; 

// ... 

string str1(" hello world! "); 
trim(str1);  // str1 == "hello world!" 
+10

-1: esto recorta; no elimina todos los espacios en blanco. –

10

Hola, se puede hacer algo por el estilo. Esta función borra 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; 
} 
+3

delgado y directo al grano, gracias. – Felipe

6
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); 
} 

usarlo:

string replace = replaceinString(thisstring, " ", "%20"); 
string replace2 = replaceinString(thisstring, " ", "-"); 
string replace3 = replaceinString(thisstring, " ", "+"); 
+1

gracias, esto funcionó como un encanto para mí. –

9

Se puede utilizar esta solución para la eliminación de un char:

#include <algorithm> 
#include <string> 
using namespace std; 

str.erase(remove(str.begin(), str.end(), char_to_remove), str.end()); 
+1

#include < string.h > usando namespace std; – slackmart

+0

Esta solución es correcta para mí. El de arriba no es. –

-1
string removespace(string str) 
{  
    int m = str.length(); 
    int i=0; 
    while(i<m) 
    { 
     while(str[i] == 32) 
     str.erase(i,1); 
     i++; 
    }  
} 
+0

Generalmente, se prefiere agregar una breve explicación a las respuestas del código. – arcyqwerty

+0

@test - '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, entonces el ciclo leerá más allá de los límites de la cadena. Probablemente deberías eliminar esta respuesta ya que necesita mucha ayuda. – jww

4

Si desea hacerlo con una macro fácil , aquí hay uno:

#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end()) 

Esto supone que ha hecho #include <string> por supuesto.

de llamadas que de este modo:

std::string sName = " Example Name "; 
REMOVE_SPACES(sName); 
printf("%s",sName.c_str()); // requires #include <stdio.h> 
+2

¿por qué usaría una macro para esto? – dani

+1

Menos teclado escribiendo para una tarea común. – Volomike

1

que utiliza el trabajo de abajo por mucho tiempo - no está seguro acerca de su complejidad.

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());

cuando se quiere eliminar el carácter ' ' y algunos por ejemplo - uso

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());

asimismo simplemente aumentar el || si el número de caracteres ¿Quieres eliminar no es 1

pero como se mencionó por otros, el borrado borrar idioma también parece estar bien.

Cuestiones relacionadas