Necesito ayuda en este codigo please

Iniciado por MellaSystems, 11 Marzo 2015, 03:54 AM

0 Miembros y 1 Visitante están viendo este tema.

MellaSystems

me da este error al ejecutar el programa:
29 C:\Users\JuanaG\Programacion\Estructura de Datos\OtroVectorEstructurado.cpp invalid use of void expression

Código (cpp) [Seleccionar]
class cEstudiante{
       private:
            string NomEst;    
       public:
            void setNomEst(string pNomEst){NomEst = pNomEst;}
            string getNomEst(){return NomEst;}  
            vector<string> vEstudiante;
            vector<string>::iterator it;
            void addNomEst(){
                 string nombre;
                 cout<<"Digite el nombre que desea agregar: ";
                 cin >> nombre;
                 for(it = vEstudiante.begin(); it != vEstudiante.end(); it++){
                   vEstudiante.push_back(setNomEst(nombre));
                 }
                 system("pause");
                 }
           
            void showNomEst(){
                 cout<<"Los nombres digitados son: "<<endl;
                 for(it = vEstudiante.begin(); it != vEstudiante.end(); ++it){
                        cout << *it;
                        }
                 cout << endl;
                 system("pause");
                 }
                         
     };


ya solucione mi error, tarde pero lo solucione... para cualquier duda:

Código (cpp) [Seleccionar]
class cEstudiante{
       private:
            vector<string> NomEst;    
       public:
            //cEstudiante(string nombre): NomEst(nombre){}
            void setNomEst(vector<string> pNomEst){NomEst = pNomEst;}
            vector<string> getNomEst(){return NomEst;}  
            vector<string>::iterator it;
           
            void addNomEst(){
                 system("cls");
                 cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<MENU INSERTAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                 string nombre;
                 cout<<"Digite el nombre que desea agregar: ";
                 fflush(stdin);
                 cin >> nombre;
                 NomEst.push_back(nombre);
                 system("pause");
                 }

void showNomEst(){
                 system("cls");
                 cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU LISTAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                 cout<<"\n\n\t\tLos nombres digitados son: "<<endl<<endl;
                 for(it = NomEst.begin(); it != NomEst.end(); ++it){
                        cout << *it << endl;
                        }
                 cout << endl;
                 system("pause");
                 }

eferion

Código (cpp) [Seleccionar]
void setNomEst(vector<string> pNomEst){NomEst = pNomEst;}

El código funciona, hasta ahí todo bien. Sin embargo te pongo un pequeño "pero". En la función de arriba, pNomEst va a ser una copia del vector que pases como parámetro. Una vez hecha la copia, el contenido de pNomEst se va a copiar en la variable interna NomEst, es decir, vas a copiar el puntero dos veces.

Este comportamiento suele ser algo a evitar por cuestiones de rendimiento. Puedes evitar una de las dos copias pasando el argumento por referencia en vez de por valor:

Código (cpp) [Seleccionar]
void setNomEst(const vector<string>& pNomEst){NomEst = pNomEst;}

Añadimos "const" porque la referencia se comporta, a efectos prácticos, como un puntero. Dado que no se desea que "pNomEst" cambie dentro de esta función, lo suyo es etiquetar la variable como "const" para asegurarnos.

Un saludo

MellaSystems

#2
Gracias por la sugerencia efeiron es de gran ayuda tu aclaracion, pero mira mi error en el codigo. Si iinserto dos nombres al querer buscar uno me salen los dos AYUDA PLEASE.

Código (cpp) [Seleccionar]
#include <iostream>
#include <string>          
#include <vector>
#include <algorithm>

using std::vector;
using std::cout;
using std::cin;
using std::string;
using std::endl;

class cEstudiante{
       private:
            vector<string> NomEst;    
       public:
            void setNomEst(const vector<string>& pNomEst){NomEst = pNomEst;}
            vector<string> getNomEst(){return NomEst;}  
            vector<string>::iterator it;
           
            void addNomEst(){
                 system("cls");
                 cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<MENU INSERTAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                 string nombre;
                 cout<<"Digite el nombre que desea agregar: ";
                 fflush(stdin);
                 cin >> nombre;
                 NomEst.push_back(nombre);
                 system("pause");
                 }
                 
            void deletNomEst(){
                 system("cls");
                 cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU BORRAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                 string borrar;
                 cout<<"Digite el nombre que desea borrar: ";
                 fflush(stdin);
                 cin >> borrar;
                 for(it = NomEst.begin(); it != NomEst.end(); ++it){
                    if((*it) == borrar){      
                       NomEst.erase(it);
                       --it;  
                       cout<<"\nNombre borrado con Exito\n\n";    
                             }
                 }
                 system("pause");
                 }
           
            void showNomEst(){
                 system("cls");
                 cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU LISTAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                 cout<<"\n\n\t\tLos nombres digitados son: "<<endl<<endl;
                 for(it = NomEst.begin(); it != NomEst.end(); ++it){
                        cout << *it << endl;
                        }
                 cout << endl;
                 system("pause");
                 }
           
            void seachNomEst(){
                 system("cls");
                 string buscar;
                 cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU BUSCAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                 cout<<"Digite el nombre que desea buscar: ";
                 fflush(stdin);
                 cin >> buscar;
                 for(it = NomEst.begin(); it != NomEst.end(); it++){
                        if((*it) == buscar ){
                         cout<<"\nEl nombre ["<< *it << "] se encuentra en la lista"<<endl;        
                          }      
                        }      
                 system("pause");
                 }
                         
     };

main(){
            cEstudiante ObjEst;
           
            int OpcMen, sigue = 1; //Variables para controlar el menu
            do {
            system("cls");
    system ("color F0");
            cout << "\n\n\t\t<<<<<<<<<<<<<<<<<<<<<<<<MENU>>>>>>>>>>>>>>>>>>>>>>>>>>\n" << endl;
            cout << "\n\n 1  ---> INSERTAR NOMBRE" << endl;
            cout << " 2  ---> BORRAR NOMBRE" << endl;
            cout << " 3  ---> MOSTRAR NOMBRE" << endl;
            cout << " 4  ---> BUSCAR NOMBRE" << endl;
            cout << " 0  ---> SALIR" << endl << endl;
            cout<<"\n\t ---> INGRESE SU OPCION: ";
    while(!(std::cin>>OpcMen))
            {
     std::cin.clear();
     std::string error;
     std::cin>>error;
     system("cls");
             cout<<"\n\tLA OPCION INGRESADA NO EXISTE\n";
     cout<<"\n\tIngrese su opci\242n nuevamente: ";
             }
        switch(OpcMen) {
    case 1:
                    ObjEst.addNomEst();                        
                break;
               
    case 2:
                      ObjEst.deletNomEst();                      
break;

    case 3:
                      ObjEst.showNomEst();
break;
                     
                case 4:
                     ObjEst.seachNomEst();
break;
                case 0:
 sigue = 0;
break;
                default:
                           cout<<"\t\tLA OPCION INGRESADA NO EXISTE\n";
                       system("cls");
}
} while(sigue);      
}


Entonces si inserto dos nombres y le doy a buscar o borrar uno de ellos me cosas que no deberia.

eferion

Código (cpp) [Seleccionar]
if((*it) == borrar){     
                       NomEst.erase(it);
                       --it;


Una vez que haces "erase", el iterador que has utilizado deja de ser válido, ya que el elemento al que apunta deja de pertenecer al vector. Cualquier operación sobre ese vector que realices después del "erase" es una operación no válida.

Para hacer esto tienes varias opciones. Yo te comento dos de ellas:

1. Creas un iterador temporal y después borras el elemento. De esta forma conservas un iterador válido después de la operación:

Código (cpp) [Seleccionar]
if((*it) == borrar){
  std::vector< std::string > itTemp = it--;
  NomEst.erase( itTemp );


Porque claro, el iterador sobre el que se hace "erase" deja de ser válido... pero el resto de iteradores siguen siendo totalmente válidos.

El problema que tiene este sistema es que si intentas eliminar el primer elemento del vector, it-- resulta entonces en una operación no válida. Puedes intentar hacer una lógica un poco más completa para detectar esta situación y actuar en consecuencia, o puedes pasar a la otra opción.

2. Hacer uso de la STL para marcar los elementos a borrar. Hay una función en la STL llamada "remove". Esta función itera un contenedor y ejecuta una comprobación sobre cada elemento. Si la condición resulta positiva, marca el elemento para eliminar. Al finalizar la función, los elementos a borrar se encontrarán al final del vector, por lo que nos podemos cargar todos de un plumazo borrando un rango de iteradores.

Código (cpp) [Seleccionar]

std::vector< std::string > itEnd = std::remove( NomEst.begin( ), NomEst.end( ), nombre );
NomEst.erase( itEnd, NomEst.end( ) );


"remove" pertenece a la librería "algorithm"

También existe la función "remove_if". Si bien esta variante es mucho más potente, puesto que permite usar una función personalizada para detectar los elementos a eliminar, es un pelín más compleja de usar y no merece la pena en este caso tan sencillo. Te lo comento por si te pica la curiosidad y quieres investigar un poco más sobre el tema.

En cuanto a tu problema con la búsqueda... fflush no se puede usar con buffer de entrada y stdin es un buffer de entrada. Conclusión, esa línea no debería estar en tu programa. Si necesitas borrar el buffer de entrada hay otros mecanismos, buscando en google encontrarás algunos), pero no creo que necesites limpiarlo en tu caso.

Un saludo.

MellaSystems

Efeiron por las ayudas que nos brindas. Estos algoritmos se ha vuelto un reto para mi. Ahora mira lo que pasa. Si inserto 3 Nombres con el metodo insertar. Ej: Jose, Rosa y Maria.

Ahora le agregue un else al metodo borrar, al yo seleccionar la opcion borrar, si borro el de las ultimas posiciones mira como sale:



y lo mismo le agregue al metodo buscar, al buscar una posicion que no sea la posicion 0 mira lo que sale:



Metodo Borrar:
Código (cpp) [Seleccionar]
void deletNomEst(){
                  system("cls");
                  cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU BORRAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                  string borrar;
                  cout<<"Digite el nombre que desea borrar: ";
                  cin.ignore(256,'\n');
                  cin >> borrar;
                  for(it = NomEst.begin(); it != NomEst.end(); ++it){
                     if((*it) == borrar){     
                        vector<string>::iterator itTemp = --it;
NomEst.erase(itTemp); 
                        cout<<"\nNombre borrado con Exito\n\n";   
                              }
                        else
                        cout<<"\nEl nombre digitado no existe\n\n";
                  }
                  system("pause");
                  }


Metodo Buscar:
Código (cpp) [Seleccionar]
void seachNomEst(){
                  system("cls");
                  string buscar;
                  cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU BUSCAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                  cout<<"Digite el nombre que desea buscar: ";
                  cin >> buscar;
                  cin.ignore(256,'\n');
                  for(it = NomEst.begin(); it != NomEst.end(); it++){
                         if((*it) == buscar ){
                          cout<<"\nEl nombre ["<< *it << "] se encuentra en la lista"<<endl;       
                           }
  cout<<"El nombre digitado no se encuentra en la lista\n";       
                         }       
                  system("pause");
                  }


y mas adelante uso la libreria "algorithm", porque quiero hacerlo con los metodos mas complejos tambien usaré el metodo find_if().

eferion

NOTA: Sería interesante que tabulases el código de una forma coherente. Sería más fácil de leer.

if((*it) == borrar){     
  vector<string>::iterator itTemp = --it;
  NomEst.erase(itTemp); 
  cout<<"\nNombre borrado con Exito\n\n";   
}
else
  cout<<"\nEl nombre digitado no existe\n\n";


Si te das cuenta, para cada elemento de la lista haces lo siguiente: Si el elemento es el buscado, lo borro y muestro un mensaje, en caso contrario indico que el nombre no existe. Queda claro entonces que, para cada elemento de la lista, o te aparece un mensaje de borrado, o te aparece uno de no encontrado.

Lo que necesitas es que el algoritmo, de alguna manera, sea capaz de saber si durante la iteración se ha borrado algún elemento. En el supuesto de que no se haya encontrado ningún elemento entonces muestras el mensaje que indica que no se ha encontrado el elemento. Esto lo puedes hacer con una variable de tipo bool (el cómo implementarlo de momento corre de tu cuenta, además te sirve para practicar)

En el segundo caso que dices sucede exactamente lo mismo. Vas a sacar si o si un mensaje por cada elemento de la lista.

Por otro lado, date cuenta de que el algoritmo, tal y como está planteado, plantea que pueden existir nombres repetidos y que, por ejemplo, en el caso de una operación de borrado se han de borrar todos los nombres que coincidan con el introducido por el usuario. No digo que sea un error, ya que eso dependerá de los requisitos de la aplicación, es un por si acaso.

Un saludo

MellaSystems

Gracias y mil gracias por tan buena explicacion efeiron. les puse unas condiciones mas al codigo y ya hace lo que quiero Thanks.

mira las modificaciones

Código (cpp) [Seleccionar]
void deletNomEst(){
                  system("cls");
                  cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU BORRAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                  string borrar;
                  int cont = -1;
                  cout<<"Digite el nombre que desea borrar: ";
                  cin.ignore(256,'\n');
                  cin >> borrar;
                  for(it = NomEst.begin(); it != NomEst.end(); ++it){
                     if((*it) == borrar){     
NomEst.erase(it);
vector<string>::iterator itTemp = --it;
                        cont++; 
                        cout<<"\nEl nombre fue borrado con Exito\n\n";   
                           }
                          } if (cont == -1){
                       cout << "El nombre a borrar no existe\n\n";
                       }cont = -1;
                  system("pause");
                  }
void seachNomEst(){
                  system("cls");
                  string buscar;
                  int PosNom=-1;
                  cout<<"\n\n\t   <<<<<<<<<<<<<<<<<<<<<MENU BUSCAR>>>>>>>>>>>>>>>>>>>>>>>\n\n\n";
                  cout<<"Digite el nombre que desea buscar: ";
                  cin >> buscar;
                  cin.ignore(256,'\n');
                  for(it = NomEst.begin(); it != NomEst.end(); it++){
                         if((*it) == buscar ){
                          PosNom++;
                          cout<<"\nEl nombre ["<< *it << "] se encuentra en la lista"<<endl;       
                           }       
                         }if(PosNom == -1){
                          cout<<"El nombre digitado no se encuentra en la lista\n";         
                          }     
                  PosNom ==-1;
                  system("pause");
                  }