Ver Mensaje Individual
  #6 (permalink)  
Antiguo 09/03/2016, 03:28
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: headers, carpetas y menúes c++

Las funciones, con paréntesis

Código C++:
Ver original
  1. Persona* getRow(std::string xnom){
  2.   Persona* toReturn = NULL; // inicialización de puntero nulo
  3.   auto it = std::find_if(lista.begin,lista.end,[&xnom](const Persona& p){
  4.     return p.nom == xnom;
  5.   });
  6.   if( it != lista.end())
  7.     toReturn = &(it); // it
  8.   return toReturn;
  9. }

begin y end son métodos de lista, luego deben llevar paréntesis.

Los includes son obligatorios

Si usas time para simular una pausa debes añadir el include donde se declara dicha función.

Cuidado con las conversiones

Código C++:
Ver original
  1. Persona* getRow(std::string xnom){
  2.   Persona* toReturn = NULL; // inicialización de puntero nulo
  3.   auto it = std::find_if(lista.begin,lista.end,[&xnom](const Persona& p){
  4.     return p.nom == xnom;
  5.   });
  6.   if( it != lista.end())
  7.     toReturn = &(it); // it
  8.   return toReturn;
  9. }

En el código que yo te puse la penúltima línea no era exactamente así, sino más bien:

Código C++:
Ver original
  1. toReturn = &(*it);

Está claro que si trabajamos con tipos nativos & y * son complementarios y se anulan entre sí, pero cuando trabajamos con clases (con las que se pueden sobrecargar dichos operadores) la cosa cambia:
  • *it te devuelve el elemento apuntado por el iterador, en este caso un objeto de tipo Persona por valor.
  • &(*it) coge el objeto por valor anterior y obtiene su dirección de memoria, que es lo que almacenas en el puntero toReturn

Cuidado con las variables no inicializadas

Las variables se han de inicializar SIEMPRE, y si no fíjate en el siguiente fragmento:

Código C++:
Ver original
  1. bool checkInt(int s){
  2.   return s >= 48 and s <= 57;
  3. }
  4.  
  5. int addInt(string type){
  6.   int intento = 1;
  7.   int nro;
  8.   while(!checkInt(nro)){
  9.     cout << "\n intento nro "<< intento << " Ingrese " << type <<": ";
  10.     cin >> nro;
  11.     intento++;
  12.   }
  13.   return nro;
  14. }

En teoría, addInt va a pedir al usuario que introduzca un número, y va a repetir la petición hasta que se introduzca un número válido. La realidad dice que nro va a tener inicialmente un valor aleatorio. Si resulta que dicho valor se encuentra en el rango (48,57) va a tomar ese valor como bueno y no va a mostrar el mensaje...

¿Soluciones? Aparte de inicializar la variable se puede usar un do-while para aumentar la protección.

La función tiene otros problemas:
  • Dado que nro es de tipo int, cin va a intentar convertir la entrada del usuario a entero. En consecuencia checkInt va a tomar como válidos números mayores de 47 y menores de 58.
  • Si se introduce un valor no numérico, p.ej "prueba", cin no va a ser capaz de convertir el dato a tipo int y activará el flag de error que no compruebas... tu programa no se va a comportar como esperas.

La solución pasaría por recoger la entrada del usuario en un string e intentar convertir dicho string a int. Si la conversión es satisfactoria el dato introducido por el usuario se toma como bueno.

Los tipos son muy importantes en C++

Código C++:
Ver original
  1. Persona* getRow(int xid){
  2.   // ...
  3. }
  4.  
  5. Persona p;
  6. p = getRow(xnom);

Si getRow devuelve un dato de tipo Persona* no puedes pretender almacenar ese retorno en una variable de tipo Persona. La gracia de devolver un puntero era para poder identificar cuándo estabamos intentando localizar un registro que no se encuentra en la lista. Puedes ahorrarte el puntero si utilizas alguna convención, por ejemplo devolver un objeto de tipo Persona con 'id=-1' en el caso de registros no válidos.

Prestar atención a los errores

Uno de los errores te está indicando que no se encuentra la sobrecarga del operador de comparación para la clase Persona. En concreto dicho operador se usa aquí:

Código C++:
Ver original
  1. void remove(Persona p){
  2.   if(check(p)){
  3.     lista.remove(p); // <<<--- AQUI!!!!
  4.   }
  5. }

Y se usa porque es la forma en la que remove puede encontrar un elemento equivalente al que le estás pasando como parámetro. Si quieres usar esta función tienes que implementar dicho operador en la clase Persona.

Y con esto el código ya debería compilarte... sigue teniendo algún error más, pero depurando el código deberíais ser capaces de localizarlos.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.