elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problema con remove_if
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema con remove_if  (Leído 1,436 veces)
DvNe

Desconectado Desconectado

Mensajes: 12


Ver Perfil
Problema con remove_if
« en: 8 Abril 2014, 17:48 pm »

Buenas, estoy intentando usar la función remove_if para eliminar espacios en blanco de una cadena de caracteres de bajo nivel. He aquí la función que he diseñado:

Código
  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cctype>
  5. #include <string>
  6. using namespace std;
  7.  
  8. class EsBlanco {
  9. public:
  10.  bool operator() (const char& c) const { return std::isspace(c); }
  11. };
  12.  
  13. int main() {
  14.  string s = "4539 4512 0398 7356";
  15.  char *letras = new char [s.length() + 1];
  16.  strcpy (letras, s.c_str());
  17.  
  18.  char * inicio = letras;
  19.  char * fin = letras + s.length();
  20.  
  21.  fin = std::remove_if(inicio,fin,EsBlanco());
  22.  
  23.  for (char * p = inicio; p != fin; ++p)
  24.     cout  << *p;
  25.  return 0;
  26. }

El problema que ocurre es que elimina los 3 espacios en blanco que hay en el string pero el numero resultante es: 4539451203987356356

Creo que se vuelven a repetir los 3 últimos números porque se eliminaron los otros 3 huecos de los espacios. Alguien podría guiarme para encontrar una solución


En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Problema con remove_if
« Respuesta #1 en: 8 Abril 2014, 18:34 pm »

No hace falta crear una clase para eso. Puedes hacerlo en una función directamente (Y para un char no hace falta una referencia):
Código
  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cctype>
  5. #include <string>
  6. using namespace std;
  7.  
  8. bool EsBlanco(const char c)
  9. {
  10.    return std::isspace(c);
  11. }
  12.  
  13. int main()
  14. {
  15.    string s = "4539 4512 0398 7356";
  16.    char *letras = new char [s.length() + 1];
  17.    strcpy (letras, s.c_str());
  18.  
  19.    char * inicio = letras;
  20.    char * fin = letras + s.length();
  21.  
  22.    fin = std::remove_if(inicio,fin,EsBlanco);
  23.  
  24.    for (char * p = inicio; p != fin; ++p)
  25.        cout  << *p;
  26.    return 0;
  27. }
  28.  

En cuanto al error, a mí me imprime el resultado correcto :huh:

De todas formas no entiendo porque usas char*. Con lo facil que sería hacerlo en el mismo string:
Código
  1. string s = "4539 4512 0398 7356";
  2. remove_if(s.begin(),s.end(),EsBlanco);
  3.  
  4. cout<<s<<endl;


« Última modificación: 8 Abril 2014, 18:36 pm por amchacon » En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
DvNe

Desconectado Desconectado

Mensajes: 12


Ver Perfil
Re: Problema con remove_if
« Respuesta #2 en: 8 Abril 2014, 18:44 pm »

A ver el caso es que en realidad no estoy usando strings, estoy usando una clase (hecha por mi) que emula el comportamiento de string en ciertos aspectos, he aquí su implementación:

Código
  1. #ifndef _CADENA_
  2. #define _CADENA_
  3. #include <iostream>
  4. #include <stdexcept>
  5.  
  6. class Cadena {
  7. public:
  8.  explicit Cadena (const size_t longitud = 0, const char cadena = ' ');
  9.  Cadena (const Cadena& );
  10.  Cadena (const char* );
  11.  
  12.  ~Cadena() {delete[] cadena_;}
  13.  
  14.  size_t longitud() const {return longitud_ - 1;}
  15.  char* c_str() const {return cadena_;}
  16.  
  17.  Cadena& operator = (const char*);
  18.  Cadena& operator = (const Cadena&);
  19.  Cadena& operator += (const Cadena&);
  20.  
  21.  char operator [] (int pos) const {return cadena_[pos];}
  22.  char& operator [] (int pos) {return cadena_[pos];}
  23.  char at(size_t) const throw (std::out_of_range);
  24.  char& at(size_t) throw (std::out_of_range);
  25.  
  26.  //  operator char*() const {return (*this).cadena_str();}
  27.  Cadena subcadena (int, int) const throw(std::out_of_range);
  28.  
  29.  friend std::ostream& operator << (std::ostream&, const Cadena&);
  30.  friend std::istream& operator >> (std::istream&, Cadena&);
  31. private:
  32.  char *cadena_;
  33.  size_t longitud_;
  34. };
  35.  
  36. Cadena operator + (const Cadena&, const Cadena&);
  37.  
  38.  
  39. bool operator == (const Cadena&, const Cadena&);
  40. bool operator != (const Cadena&, const Cadena&);
  41. bool operator < (const Cadena&, const Cadena&);
  42. bool operator <= (const Cadena&, const Cadena&);
  43. bool operator > (const Cadena&, const Cadena&);
  44. bool operator >= (const Cadena&, const Cadena&);
  45. #endif

Código
  1. #include <iostream>
  2. #include <cstring>
  3. #include <stdexcept>
  4.  
  5. #include "cadena.h"
  6.  
  7. using namespace std;
  8.  
  9. Cadena::Cadena (const size_t longitud, const char caracter) : longitud_(longitud+1) {
  10.  cadena_ = new char[longitud_];
  11.  for (size_t i = 0; i < longitud; ++i)
  12.    cadena_[i] = caracter;
  13.  cadena_[longitud] = '\0';
  14. }
  15.  
  16. Cadena::Cadena (const Cadena &cadena1) : longitud_(cadena1.longitud() + 1){
  17.  cadena_ = new char[longitud_];
  18.  strcpy(cadena_,cadena1.c_str());
  19. }
  20.  
  21. Cadena::Cadena (const char *cadena) : longitud_(strlen(cadena) + 1){
  22.  cadena_ = new char[longitud_];
  23.  strcpy(cadena_,cadena);
  24. }
  25.  
  26. Cadena& Cadena::operator = (const char* cadena) {
  27.  longitud_ = strlen(cadena) + 1;
  28.  cadena_ = new char[longitud_];
  29.  strcpy(cadena_,cadena);
  30.  return (*this);
  31. }
  32.  
  33. Cadena& Cadena::operator = (const Cadena &cadena1) {
  34.  if (this != &cadena1) {
  35.    delete[] cadena_;
  36.    if (cadena1.c_str()) {
  37.      longitud_ = cadena1.longitud() + 1;
  38.      cadena_ = new char[longitud_];
  39.      strcpy(cadena_,cadena1.c_str());
  40.    }
  41.    else
  42.      cadena_ = NULL;
  43.  }
  44.  return (*this);
  45. }
  46.  
  47. Cadena& Cadena::operator += (const Cadena &cadena1) {
  48.  Cadena cadena2 (longitud() + cadena1.longitud());
  49.  strcpy(cadena2.cadena_,cadena_);
  50.  strcat(cadena2.cadena_,cadena1.cadena_);
  51.  (*this) = cadena2;
  52.  return (*this);
  53. }
  54.  
  55. char Cadena::at(size_t pos) const throw(std::out_of_range) {
  56.  if (pos < 0 || pos > longitud())
  57.    throw (std::out_of_range("Posicion fuera de rango"));
  58.  else if ((*this)[pos] == 0)
  59.    throw (std::out_of_range("Posicion inexistente"));
  60.  else
  61.    return (*this)[pos];
  62. }
  63.  
  64. char& Cadena::at(size_t pos) throw(std::out_of_range) {
  65.  if (pos < 0 || pos > longitud())
  66.    throw (std::out_of_range("Posicion fuera de rango"));
  67.  else if ((*this)[pos] == 0)
  68.    throw (std::out_of_range("Posicion inexistente"));
  69.  else
  70.    return (*this)[pos];
  71. }
  72.  
  73. Cadena operator + (const Cadena &cad1, const Cadena &cad2) {
  74.  Cadena aux(cad1);
  75.  aux += cad2;
  76.  return aux;
  77. }
  78. /* Tam_i no puede ser negativo */
  79. Cadena Cadena::subcadena (int pos_i, int tam_i) const  throw(std::out_of_range) {
  80.  if ((size_t) pos_i < 0 || (size_t) pos_i > longitud() - 1)
  81.    throw (std::out_of_range("Posicion inicial fuera de rango"));
  82.  
  83.  if (tam_i < 0 || (size_t) pos_i + tam_i > longitud())
  84.    throw (std::out_of_range("Posicion fuera de rango"));
  85.  
  86.  Cadena cadena (tam_i);
  87.  size_t i = 0;
  88.  for (size_t k = pos_i; k < (size_t) tam_i + pos_i; k++) {
  89.    cadena.at(i) = at(k);
  90.    i++;
  91.  }
  92.  return cadena;
  93. }
  94. /**
  95.  * strcmp(x,y)
  96.  * Si x == y return 0;
  97.  * Si x <  y return -1;
  98.  * Si x >  y return 1;
  99.  */
  100.  
  101. bool operator == (const Cadena &cad1, const Cadena &cad2) {
  102.  return !(strcmp(cad1.c_str(),cad2.c_str()));
  103. }
  104.  
  105. bool operator != (const Cadena &cad1, const Cadena &cad2) {
  106.  return !(cad1 == cad2);
  107. }
  108.  
  109. bool operator < (const Cadena &cad1, const Cadena &cad2) {
  110.  if (strcmp(cad1.c_str(),cad2.c_str()) >= 0)
  111.    return false;
  112.  return true;
  113. }
  114.  
  115. bool operator <= (const Cadena &cad1, const Cadena &cad2) {
  116.  return cad1 < cad2 || cad1 == cad2;
  117. }
  118.  
  119. bool operator > (const Cadena &cad1, const Cadena &cad2) {
  120.  if (strcmp(cad1.c_str(),cad2.c_str()) <= 0)
  121.    return false;
  122.  return true;
  123. }
  124.  
  125. bool operator >= (const Cadena &cad1, const Cadena &cad2) {
  126.  return cad1 > cad2 || cad1 == cad2;
  127. }
  128.  
  129. ostream& operator << (ostream &output, const Cadena &c) {
  130.  output << c.c_str();
  131.  return output;
  132. }
  133.  
  134. istream& operator >> (istream &input, Cadena &c) {
  135.  char* entrada = new char[32];
  136.  entrada[0] = '\0';
  137.  input.width(32);
  138.  input >> entrada;
  139.  
  140.  c = entrada;
  141.  delete[] entrada;
  142.  return input;
  143. }

Por tanto, realmente, la variable s sería de tipo CADENA y como esta clase no es tan potente como la string no puedo hacer lo de s.begin() ni s.end().

Ahora bien te puedes preguntar, por qué no uso string y me dejo de líos? Porque es un proyecto para la universidad y tengo prohibido usar esa clase en el proyecto  :(

En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Problema con remove_if
« Respuesta #3 en: 8 Abril 2014, 21:09 pm »

Pues revisalo porque he vuelto a copypastear tu código y me lo hace bien :huh:

De hecho, incluso lo he hecho con strings y he comparado salidas. Son identicas:
Código
  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cctype>
  5. #include <string>
  6. using namespace std;
  7.  
  8. class EsBlanco
  9. {
  10. public:
  11.    bool operator() (const char& c) const
  12.    {
  13.        return std::isspace(c);
  14.    }
  15. };
  16.  
  17. int main()
  18. {
  19.    string s = "4539 4512 0398 7356";
  20.    string b = s;
  21.  
  22.    char *letras = new char [s.length() + 1];
  23.    strcpy (letras, s.c_str());
  24.  
  25.    char * inicio = letras;
  26.    char * fin = letras + s.length();
  27.  
  28.    fin = std::remove_if(inicio,fin,EsBlanco()); // metodo por char*
  29.    b = string(s.begin(),std::remove_if(s.begin(),s.end(),EsBlanco())); // metodo por strings
  30.  
  31.    *fin = 0; // caracter nulo
  32.  
  33.    string a = inicio;
  34.  
  35.    if (a == b) cout<<"Funciono!"<<endl;
  36.    else cout<<"No funciono! :("<<endl;
  37.  
  38.    cout<<b<<endl;
  39.    for (char * p = inicio; p != fin; ++p)
  40.        cout  << *p;
  41.    return 0;
  42. }

Ambos metodos me generan la misma salida. No consigo generar tu error...
« Última modificación: 8 Abril 2014, 21:11 pm por amchacon » En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema BlueZScanner y problema de conexión
Hacking Mobile
Kasswed 3 6,304 Último mensaje 6 Mayo 2006, 22:04 pm
por Gospel
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines