Estoy escribiendo una pieza de software, y me requieren para manejar los datos que obtengo de una página web con libcurl. Cuando llego a los datos, por alguna razón no tiene saltos de línea adicionales en el mismo. Tengo que encontrar una manera para permitir sólo letras, números y espacios. Y eliminar todo lo demás, incluyendo los saltos de línea. ¿Hay alguna forma fácil de hacer esto? Gracias.

  • ¿Cómo está el almacenamiento de los datos? En un char buffer o un string?

11 Comentarios

  1. 43

    Escribir una función que toma un char y devuelve true si desea eliminar ese carácter o false si desea mantener:

    bool my_predicate(char c);

    A continuación, utilizar la std::remove_if algoritmo para eliminar los caracteres no deseados de la cadena:

    std::string s = "my data";
    s.erase(std::remove_if(s.begin(), s.end(), my_predicate), s.end());

    Dependiendo de los requisitos, usted puede ser capaz de utilizar uno de la Biblioteca Estándar de predicados, como std::isalnum, en lugar de escribir su propio predicado (usted dijo que usted necesita para que coincida con los caracteres alfanuméricos y espacios, así que tal vez este no se ajusta exactamente lo que usted necesita).

    Si quieres usar la Biblioteca Estándar de std::isalnum función, usted tendrá un yeso para eliminar la ambigüedad entre el std::isalnum función de la Biblioteca Estándar de C encabezado <cctype> (que es el que quieres usar) y el std::isalnum en el Estándar de C++ de encabezado de la Biblioteca <locale> (que no es el que usted desea utilizar, a menos que usted desea realizar una configuración regional específica de la cadena de procesamiento):

    s.erase(std::remove_if(s.begin(), s.end(), (int(*)(int))std::isalnum), s.end());

    Esto funciona igual de bien con cualquiera de la secuencia de contenedores (incluidos los std::string, std::vector y std::deque). Este modismo es comúnmente referido como el «borrar/eliminar» modismo. El std::remove_if algoritmo también el trabajo con las matrices. El std::remove_if hace sólo un único paso a través de la secuencia, por lo que tiene el tiempo lineal de la complejidad.

    • Ello, no la mía.
    • Es la eliminación de alfa numéricos, caracteres en lugar de los caracteres especiales. estoy haciendo algo mal ?
    • Le van a quitar caracteres alfanuméricos y no caracteres especiales porque (int(*)(int))std::isalnum volverá true siempre un carácter alfanumérico que se encuentre y que personaje será borrado de la cadena.
    • (int(*)(int))std::isalnum mantendrá sólo los caracteres especiales, en lugar de utilizar std::not1(std::ptr_fun( (int(*)(int))std::isalnum )) a invertir su lógica
    • Como dijo esto eliminará los caracteres alfanuméricos, debe ser invertida
  2. 10

    Los usos anteriores de std::isalnum no compile con std::ptr_fun sin pasar por la unario argumento se requiere, por lo tanto esta solución con una función lambda debe encapsular la respuesta correcta:

    s.erase(std::remove_if(s.begin(), s.end(), 
    []( auto const& c ) -> bool { return !std::isalnum(c); } ), s.end());
    • ¿Por qué es necesario incluir el &c, en el auto, por que no c?
    • Sí, usted puede tener la firma desea, puede utilizar un valor, un valor y un std::move, un perfecto reenvío, etc… creo que el auto const& es la apuesta más segura de no saber el tipo real, ya que están garantizados sin más caro copias, aunque en algunos casos un valor/movimiento es aún más eficiente. Y en los mismos casos, incluso un simple valor intrínseco tipos.
  3. 4

    Siempre se puede recorrer y sólo erase todos los que no sean caracteres alfanuméricos si usted está usando string.

    #include <cctype>
    
    size_t i = 0;
    size_t len = str.length();
    while(i < len){
        if (!isalnum(str[i]) || str[i] == ' '){
            str.erase(i,1);
            len--;
        }else
            i++;
    }

    A alguien mejor con el Estándar Lib probablemente puede hacer esto sin un bucle.

    Si usted está usando un char búfer, puede recorrer y si un carácter no alfanumérico, cambio de todos los personajes después de que uno hacia atrás (para sobrescribir el infractor carácter):

    #include <cctype>
    
    size_t buflen = something;
    for (size_t i = 0; i < buflen; ++i)
        if (!isalnum(buf[i]) || buf[i] != ' ')
            memcpy(buf[i], buf[i + 1], --buflen - i);
    • Eliminar el bucle implicaría la borrar-eliminar modismo
    • En el segundo caso, si se mantiene la fuente y el destino de los punteros, usted puede evitar hacer un memcpy del resto de búfer cada vez que un personaje debe ser eliminado. es decir, para (char *s = buf, *d = buf; *s; ++s) { if (!isalnum(*s) || *s != ») *d++ = *s; } *d = 0;
  4. 2
    #include <cctype>
    #include <string>
    #include <functional>
    
    std::string s = "Hello World!";
    s.erase(std::remove_if(s.begin(), s.end(),
        std::not1(std::ptr_fun(std::isalnum)), s.end()), s.end());
    std::cout << s << std::endl;

    Resultados en:

    "HelloWorld"

    Utilizar isalnum para determinar si o no a cada carácter alfa numérico, a continuación, utilizar ptr_fun para pasar a la función para not1 que No tienen el valor devuelto, dejando sólo la alfanuméricos lo que usted quiere.

  5. 1

    Puede utilizar el eliminar-borrar algoritmo de esta manera –

    //Removes all punctuation       
    s.erase( std::remove_if(s.begin(), s.end(), &ispunct), s.end());
  6. 1

    Sólo se extiende James McNellis del código un poco más. Su función es la eliminación de alnum caracteres en lugar de no-alnum queridos.

    Para eliminar las no alnum caracteres de una cadena. (alnum = alfabético o numérico)

    • Declarar una función (isalnum devuelve 0 si pasa char no es alnum)

      bool isNotAlnum(char c) {
          return isalnum(c) == 0;
      }
    • Y, a continuación, escribir este

      s.erase(remove_if(s.begin(), s.end(), isNotAlnum), s.end());

    a continuación, su cadena es sólo con alnum caracteres.

  7. 1

    A continuación el código debería funcionar bien para la cadena dada s. Es la utilización de <algorithm> y <locale> bibliotecas.

    std::string s("He!!llo  Wo,@rld! 12 453");
    s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return !std::isalnum(c); }), s.end());
  8. 0

    Las siguientes obras para mí.

    str.erase(std::remove_if(str.begin(), str.end(), &ispunct), str.end());
    str.erase(std::remove_if(str.begin(), str.end(), &isspace), str.end());
  9. 0
    void remove_spaces(string data)
    { int i=0,j=0;
        while(i<data.length())
        {
            if (isalpha(data[i]))
            {
            data[i]=data[i];
            i++;
            }
            else
                {
                data.erase(i,1);}
        }
        cout<<data;
    }
  10. 0

    La mencionada solución

    s.erase( std::remove_if(s.begin(), s.end(), &std::ispunct), s.end());

    es muy bonito, pero lamentablemente no funciona con los caracteres como la ‘Ñ’ en Visual Studio (modo de depuración), porque de esta línea:

    _ASSERTE((unsigned)(c + 1) <= 256)

    en isctype.c

    Así, yo recomendaría algo como esto:

    inline int my_ispunct( int ch )
    {
        return std::ispunct(unsigned char(ch));
    }
    ...
    s.erase( std::remove_if(s.begin(), s.end(), &my_ispunct), s.end());

Dejar respuesta

Please enter your comment!
Please enter your name here