Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: guanaco112 en 1 Marzo 2012, 06:23 am



Título: ayuda con listas enlazadas en c++!!!!
Publicado por: guanaco112 en 1 Marzo 2012, 06:23 am
hola si me pueden ayudar con este problema, recien empiezo a programar en c++ y me dejaron un problema con listas enlazadas, en el programa pide ingresar el nombre y hacer una operacion de retirar dinero como en un cajero, y que pueda ser mas de una persona que haga esta operacion, y que el programa parara cuando ya no haya dinero digamos en el cajero...(la cantidd de dinero disponible son 40000 pesos)..esto es lo que llevo, solo me deja ingresar nombre, pero no se como hacer la operacion de resta, aparte tampoco se como hacer para que al finalizar la operacion me vuelva a pedir si quiero ingresar otro nombre :(
gracias!!!


#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct _contacto {
    char nombre[33];
    int retirar;
        struct _contacto *siguiente;
};
struct _contacto *primero, *ultimo;

void agregar_contacto()
{
     struct _contacto *nuevo;
     nuevo = (struct _contacto*)malloc(sizeof(struct _contacto));
     if(nuevo==NULL){
         cout<<"\nNo hay espacio suficiente.";
         return;
     }
     cout<<"\n\ningrese su nombre\n";
     cout<<"------------------";
     cout<<"\nNombre: ";
      fgets(nuevo->nombre,32,stdin);
     nuevo->siguiente = NULL;
     if(primero==NULL){
         primero = nuevo;
         ultimo = nuevo;
     } else {
         ultimo->siguiente = nuevo;
         ultimo = nuevo;
     }
}

void retirar_1()
{
        int retirar;
     struct _contacto *nuevo;
     nuevo = (struct _contacto*)malloc(sizeof(struct _contacto));
     if(nuevo==NULL){
         cout<<"\nNo hay espacio suficiente.";
         return;
     }


  cout<<"ingrese cantidad a retirar:";
  cin>>retirar;
  nuevo->retirar;

  cout<<endl<<"lo retirado fue:"<<nuevo->retirar;


      nuevo->retirar;
     nuevo->siguiente = NULL;
     if(primero==NULL){
         primero = nuevo;
         ultimo = nuevo;
     } else {
         ultimo->siguiente = nuevo;
         ultimo = nuevo;
     }
}


 void mostrar(){
ultimo=primero;
while(ultimo!=NULL){
cout<<endl<<"nombre:"<<primero->nombre;
cout<<endl<<"retiro:"<<primero->retirar;
ultimo=ultimo->siguiente;
}
}


void mostrar_menu()
{
     cout<<"\n\n\n Bienvenido\n";
     cout<<"======\n";
     cout<<"1. Agregar nombre\n";
     cout<<"2. retirar dinero\n";
    cout<<"3. mostrar datos\n";
     cout<<"4. Salir\n";
}

int main()
{
    int opcion = 0;
    char bufferOpcion[5];
    while(opcion!=4){
        mostrar_menu();
        fgets(bufferOpcion,sizeof(bufferOpcion),stdin);
        sscanf(bufferOpcion, "%d", &opcion);
        switch(opcion){
            case 1:
                agregar_contacto();
                break;
                case 2:
                retirar_1();
                break;

                 case 3:
                mostrar();
                break;



        }
    }
    return 0;
    getchar();
}


Título: Re: ayuda con listas enlazadas en c++!!!!
Publicado por: rir3760 en 2 Marzo 2012, 02:32 am
Espero lo tomes como una critica constructiva: si estas aprendiendo C++ te deberian enseñar eso y no la base de C. El programa tiene varios errores algunos de ellos basicos y que no deberian existir en un programa cuya unica finalidad (de nuevo en el caso de C++) es la practica del uso de punteros.

Para empezar los nombres de todos los encabezados estan mal, deberian ser:
Código
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cstdlib>
  5.  
  6. // Por el momento basta, despues habra que incluir solo lo necesario ...
  7. using namespace::std;
  8.  
  9. // ...

Hay que evitar el uso de extensiones como la biblioteca conio de Borland. Por favor lee el tema |Lo que no hay que hacer en C/C++. Nivel basico| (http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html).

Tambien debes separar la operacion para agregar un retiro en partes: reserva de memoria (creacion del nodo), peticion de los datos (lectura de un registro) y agregar el registro a la lista

El error principal en el programa se debe a la funcion "mostrar":
Código
  1. void mostrar()
  2. {
  3.   ultimo = primero;
  4.  
  5.   while (ultimo != NULL){
  6.      cout << endl << "nombre:" << primero->nombre;
  7.      cout << endl << "retiro:" << primero->retirar;
  8.  
  9.      ultimo = ultimo->siguiente;
  10.   }
  11. }
Si la lista contiene al menos un nodo al terminar esa funcion "ultimo" no apunta a ese nodo, su valor es NULL y cuando se trate de agregar un nodo a la lista el programa va a reventar (comportamiento no definido).

El programa con la mayoria de las correcciones:
Código
  1. #include <iostream>
  2. #include <cstdio>
  3.  
  4. using namespace::std;
  5.  
  6. struct contacto {
  7.   char nombre[33];
  8.   int retirar;
  9.   struct contacto *siguiente;
  10. };
  11. contacto *primero, *ultimo;
  12.  
  13. contacto *crear();
  14. void agregar (contacto *nuevo);
  15. void agregar_retiro();
  16. void mostrar();
  17. void liberar();
  18.  
  19. int main()
  20. {
  21.   char temp[1024]; // O algun valor apropiado ...
  22.   int opcion;
  23.  
  24.   do {
  25.      cout  << "Bienvenido" << endl
  26.            << "1. Agregar retiro" << endl
  27.            << "2. Mostrar datos" << endl
  28.            << "3. Salir" << endl;
  29.      cin.getline (temp, 1024);
  30.      sscanf (temp, "%d", &opcion);
  31.  
  32.      switch (opcion) {
  33.      case 1:
  34.         agregar_retiro();
  35.         break;
  36.      case 2:
  37.         mostrar();
  38.         break;
  39.      case 3:
  40.         break;
  41.      default:
  42.         cout << "Opcion no valida!" << endl;
  43.         break;
  44.      }
  45.   } while (opcion != 3);
  46.  
  47.   liberar();
  48.  
  49.   return 0;
  50. }
  51.  
  52. contacto *crear()
  53. {
  54.   contacto *nuevo;
  55.  
  56.   nuevo = (contacto *) malloc (sizeof * nuevo);
  57.   if (!nuevo) {
  58.      cerr << "No hay espacio suficiente" << endl;
  59.      exit (1);
  60.   }
  61.  
  62.   nuevo->siguiente = 0;
  63.   return nuevo;
  64. }
  65.  
  66. void agregar (contacto *nuevo)
  67. {
  68.   if (!primero)
  69.      primero = nuevo;
  70.   else
  71.      ultimo->siguiente = nuevo;
  72.   ultimo = nuevo;
  73. }
  74.  
  75. void agregar_retiro()
  76. {
  77.   char temp[1024]; // O algun valor apropiado ...
  78.  
  79.   contacto *nuevo = crear();
  80.  
  81.   cout << "Ingrese su nombre: ";
  82.   cin.getline (nuevo->nombre, 33);
  83.  
  84.   cout << "Ingrese el retiro: ";
  85.   cin.getline (temp, 1024);
  86.   sscanf (temp, "%d", &nuevo->retirar);
  87.  
  88.   agregar (nuevo);
  89. }
  90.  
  91. void mostrar()
  92. {
  93.   contacto *p;
  94.  
  95.   for (p = primero; p; p = p->siguiente) {
  96.      cout << "Nombre: " << p->nombre << endl;
  97.      cout << "Retiro: " << p->retirar << endl;
  98.   }
  99. }
  100.  
  101. void liberar()
  102. {
  103.   contacto *siguiente;
  104.  
  105.   while (primero) {
  106.      siguiente = primero->siguiente;
  107.      free (primero);
  108.      primero = siguiente;
  109.   }
  110. }

Falta agregar los detalles que mencionas, eso te toca a ti.

Por cierto: el uso de getline y sscanf es solo un "parche mal puesto", lo politicamente correcto es utilizar las clases que la biblioteca estandar de C++ provee para esas operaciones como "string" y "stringstream".

Un saludo


Título: Re: ayuda con listas enlazadas en c++!!!!
Publicado por: guanaco112 en 2 Marzo 2012, 05:03 am
MUCHAS GRACIAS POR SUS CONSEJOS , ME HA AYUDADO MUCHISIMO!!!



solo una duda??
la variable temp que funcion tiene???
gracias de nuevo!!!


Título: Re: ayuda con listas enlazadas en c++!!!!
Publicado por: rir3760 en 2 Marzo 2012, 14:18 pm
Tiene la misma función que el array de caracteres utilizado en el programa original (tu programa): obtener una linea de texto y de ahí extraer el retiro.

Un saludo