/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Practica de tablas hash

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
xgusix



Registrado: 13 Sep 2007
Mensajes: 3

MensajePublicado: 13/09/2007 1:50 pm
Título: Practica de tablas hash

Dependo de la entrega de esta practica para aprobar EDD y me he trabado por que me da un problema de compilación por movidas con los punteros y por otro lado cuando lo he conseguido solucionar (cosa que ahora no soy capaz) me rompe a media ejecución.

Me gustaría que me ayudaseis con la compilación y a solucionar esa parte de la ejecución que peta (aparece comentada en el codigo fuente)
El enunciado, codigo fuente y fichero necesario están en:




Muchas gracias![/url]
Volver arriba
digies



Registrado: 18 Nov 2005
Mensajes: 241
Ubicación: Cono Sur

MensajePublicado: 13/09/2007 2:12 pm
Título:

Hola

Sería un gusto ayudarte, pero deberías colocar este tema en Trabajos de Clase. Y también colocar el código completo en el foro, porque eso de estar bajando por medio de otro enlace es un poco tedioso y se pierde tiempo.

Un saludo
Volver arriba
xgusix



Registrado: 13 Sep 2007
Mensajes: 3

MensajePublicado: 13/09/2007 3:14 pm
Título:

Si bueno, pero ya que está aquí pues la dejo aquí. Pero gracias Very Happy

A ver... he seguido pegandome con ello y ahora tengo otro problema:

En esta función todo va bien, excepto en poo = *thash[i]; que poo no coge el valor de thash[i], si teneis alguna solución a esta función, estaría agradecido. Wink

void MostrarTablaHash(T_CLIENTE *thash[])
{
//Inicialización de variables
int i;
T_CLIENTE poo;

printf("\n\n\n %d punto",poo.id_cliente);
printf("%f",poo.gasto_mensual);

printf("\n\n\tLa tabla hash obtenida ha sido:\n");
printf("\nPosicion\t\tIdentificador\t\tGasto Mensual");
printf("\n-----------------------------------------------------------\n");

for(i=0; i<=TAM_TABLA; i++)
{
if (thash[i] != NULL)
{
poo = *thash[i];
printf ("\n%d\t\t\t%d\t\t\t%f",i,poo.id_cliente,poo.gasto_mensual);
}
}

}
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3657
Ubicación: Mexico

MensajePublicado: 13/09/2007 3:58 pm
Título:

Con solo ese fragmento de codigo que expones no es posible conocer que errores hay en tu programa. Si quieres que alguien te ayude tienes que publicar el codigo fuente completo e indicar cuales son tus dificultades con este.

Tambien nos ayudarias indicando el lenguaje, compilador y plataforma que utilizas.

Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
xgusix



Registrado: 13 Sep 2007
Mensajes: 3

MensajePublicado: 13/09/2007 4:12 pm
Título:

No pongo el codigo completo porque el problema lo da ahí exactamente... pero bueno:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define TAM_TABLA 1000
#define N 20

typedef struct {
int id_cliente;
float gasto_mensual;
} T_CLIENTE;


/* Prototipos de las funciones */
void InicializarTabla(T_CLIENTE *thash[]);

int LeerInformacion(T_CLIENTE *thash[]);

void MostrarTablaHash(T_CLIENTE *thash[]);

int ObtencionClientesEstrella(T_CLIENTE *thash[],float gasto_a_superar);

void MostrarClientesEstrella(T_CLIENTE *thash[], int clientes_estrella, int gasto_a_superar);

void Limpiar_Cadena(char *cadena);

int main(int argc, char *argv[])
{
T_CLIENTE *thash[TAM_TABLA];
int clientes_estrella;
float gasto_a_superar;
int control;

if(!(*thash=(T_CLIENTE*)malloc(sizeof(T_CLIENTE)))) return -1;

InicializarTabla(thash);

control = LeerInformacion(thash);
if (control != 0)
{
printf("\nLa tabla hash obtenida ha sido:");
MostrarTablaHash(thash);

printf("\nIndica el gasto medio mensual a superar: ");
scanf("%f", &gasto_a_superar);

clientes_estrella = ObtencionClientesEstrella(thash,gasto_a_superar);
MostrarClientesEstrella(thash, clientes_estrella,gasto_a_superar);
}
printf("\nFin del programa");
return 0;
}

void InicializarTabla(T_CLIENTE *thash[])
{
int i;

for (i=0; i<TAM_TABLA; i++)
{
thash[i] = NULL;
}
}


int LeerInformacion(T_CLIENTE *thash[])
{
FILE *punt;
char nombre[N];
T_CLIENTE cliente;
int cont;
int control;
int poo;
int control2;

printf("\nIntroduzca el nombre del fichero binario: ");
fflush (stdin);
fgets (nombre, N, stdin);
Limpiar_Cadena (nombre);


control2 = 1;
/* Apertura del fichero original, para lectura en binario*/
punt = fopen (nombre, "rb");

if (punt==NULL)
{
printf("\nNo se puede abrir el fichero");
control2 = 0;
}
else
{
control = 1;
cont = 0;
while(!feof(punt))
{
fread(&cliente,sizeof(T_CLIENTE),1,punt);
control = 0;
poo = cliente.id_cliente%TAM_TABLA;
while (control != 1)
{
if (thash[poo]==NULL)
{
thash[poo]=&cliente;
control = 1;
}
else
{
poo++;
}
}
}
}
return control2;
}

void Limpiar_Cadena(char *cadena)
{
int i;
i=0;

while (cadena[i] != '\n' && cadena[i] != '\0')
{
i++;
}

if (cadena[i] == '\n')
{
cadena[i] = '\0';
}
}

void MostrarTablaHash(T_CLIENTE *thash[])
{
//Inicialización de variables
int i;
T_CLIENTE poo;

printf("\n\n\n %d punto",poo.id_cliente);
printf("%f",poo.gasto_mensual);

printf("\n\n\tLa tabla hash obtenida ha sido:\n");
printf("\nPosicion\t\tIdentificador\t\tGasto Mensual");
printf("\n-----------------------------------------------------------\n");

for(i=0; i<=TAM_TABLA; i++)
{
if (thash[i] != NULL)
{
//++++++++++++++NO VA BIEN,POO no coge los valores de la tabla++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

poo = *thash[i];
printf ("\n%d\t\t\t%d\t\t\t%f",i,poo.id_cliente,poo.gasto_mensual);
}
}

}

int ObtencionClientesEstrella(T_CLIENTE *thash[],float gasto_a_superar)
{
int i;
int cont;
T_CLIENTE poo;

cont = 0;

for(i=0; i<TAM_TABLA; i++)
{

if (thash[i] != NULL)
{
poo = *thash[i];
if (poo.gasto_mensual>gasto_a_superar)
{
cont++;
}
}
}

printf ("\nHay %d clientes que superan el gasto medio mensual de %f euros", cont, gasto_a_superar);
return cont;

}

void MostrarClientesEstrella(T_CLIENTE *thash[], int clientes_estrella,int gasto_a_superar)
{
int i;
int cont;
T_CLIENTE poo;

cont = 0;


if (clientes_estrella !=0)
{
printf ("\n\nIdentificador\t\tGasto Medio Mensual");
printf ("\n-----------------------------------------------");
for(i=0; i<TAM_TABLA; i++)
{
if (thash[i] != NULL)
{
poo = *thash[i];
if (poo.gasto_mensual>gasto_a_superar)
{
printf("\n%d\t\t%f",poo.id_cliente,poo.gasto_mensual);
}
}
}
}
else
{
printf("\nNo hay clientes estrella");
}

}

El compilador es el mingw y por lo tanto es en windows, el lenguaje: c.

El error se repetirá también en las siguientes funciones porque lo asigno igual así que si me lo podéis solucionar, lo agradecería.


Muchas gracias por los consejos!! Very Happy
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3657
Ubicación: Mexico

MensajePublicado: 14/09/2007 7:18 am
Título:

xgusix escribió:
No pongo el codigo completo porque el problema lo da ahí exactamente... pero bueno:

En programas medianamente complejos es comun que un error se genere en una parte del programa y se detecte en otra, un ejemplo casi perfecto de esto es tu programa.

En este el error principal se origina en un error de diseño en la funcion main:
Código:
T_CLIENTE *thash[TAM_TABLA];

/* ... */

if (!(*thash = (T_CLIENTE *) malloc(sizeof(T_CLIENTE))))
   return -1;

InicializarTabla(thash);

Aqui tienes un array de punteros, al ser este una variable local el valor inicial de todos sus elementos es "no definido" o "basura", antes de ser utilizados debes darle un valor inicial valido mediante la funcion malloc pero esto solo sucede con el primer elemento, todos los demas no lo son y generarian errores de cualquier tipo al tratar de utilizarlos.

Para corregir esto habra que reservar memoria para cada elemento del array:
Código:
int i;

for (i = 0; i < TAM_TABLA; i++)
   if ((thash[i] = malloc(sizeof *thash[i])) == NULL)
      return EXIT_FAILURE;


Ahora bien, esto entraria en conflicto con la funcion:
Código:
void InicializarTabla(T_CLIENTE *thash[])
{
   int i;
   
   for (i = 0; i < TAM_TABLA; i++)
      thash[i] = NULL;
}

Ya que primero se declararia el array y se asignaria (bien o mal) un valor a los elementos de este, finalmente se llama esta funcion y todos los elementos del array se les asigna NULL. Esto no es correcto, el orden debe ser:

1) Declaracion
2) Inicializacion.
2) Asignacion.

Los dos primeros pasos se pueden realizar con una sola sentencia que declare el array e inicialize sus elementos a cero (NULL en el caso de punteros):
Código:
T_CLIENTE *thash[TAM_TABLA] = {0}; /* o {NULL} */

Esta sentencia declararia al array thash y daria como valor inicial a todos sus elementos el valor 0 (sinonimo de NULL en el caso de punteros).

Despues de esto lo que debes hacer es desarrollar una funcion que reserve memoria mediante malloc para un numero determinado de elementos, por ejemplo:
Código:
/*
** Esta funcion reserva memoria para
** los primeros "num_elem" elementos
*/
int reserva_N(T_CLIENTE *thash[], int num_elem)
{
   int i;
   
   for (i = 0; i < num_elem; i++)
      if ((thash[i] = malloc(sizeof *thash[i])) == NULL)
         return 0; /* retorna falso en caso de error */
   
   return 1; /* retorna verdadero si todo va bien */
}


La siguiente funcion que se llama es "LeerInformacion", en esta un error es asignar a los elementos de la tabla thash la direccion en memoria de una variable local:
Código:
thash[poo] = &cliente;

Cuando esa funcion finaliza la memoria utilizada por sus variables (en este caso "cliente") se libera y esto resulta en mas direcciones de memoria no validas.

Finalmente el error lo detectaste en la funcion "MostrarTablaHash".

Aparte de eso habria que hacerle varias modificaciones al programa como:

* Cambiar la definicion de main a "int main(void)" ya que no utilizas los argumentos pasados mediante la linea de comandos.

* Evitar el uso de fflush(stdin), mas informacion sobre esto en la base de datos de los foros.

* La funcion "Limpiar_Cadena" se puede acortar a:
Código:
void Limpiar_Cadena(char *cadena)
{
   char *nl;
   
   if ((nl = strchr(cadena, '\n')) != NULL)
      *nl = '\0';
}


Tal vez el programa tenga mas errores pero solo lo revise superficialmente.

Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com