PDA

Ver la Versión Completa : Ayuda con programacion en C please!!


Umec
04-06-2008, 18:49:17
Bueno pue el tema es que estoy con el proyecto final de curso de 1º de DAI(desarrollo de aplicaciones informaticas) y bueno...pues estoy desarrollando en C(no C++)un sistema de gestion de entradas de un campo de futbol.El problema me surge que no consigo modificar un dato especifico de un partido.Me explico:

Tengo estas estructuras://tengo mas pero estas son las implicadas

typedef struct{int nlocalidad; //estructura para las localidades
int fila;
int zona;
float precio;
int estado;
}Tlocalidades;

typedef struct{int jornada; //estructura para lso partidos,contiene otras estructuras
cadena rival;
Tfecha fecha;
Thora hora;
int aforo;
float recaudacion;
char cerrado;
Tlocalidades localidad[280];
}Tpartido;

typedef struct nodo{Tabonado info;//estructura para punteros de la lista
Tpartido info3;
nodo *siguiente;
}nodo;
El caso es que cunado voy a vender una entrada,le pido que me meta el partido al que dessea asistir y con otra funcion busco el partido(por jornada) y m devuelve un puntero al partido.Despues le presento un menu con las zonas del estadio y segun el menu una variable llamada zona se iguala a 1,2,3 o 4 segun la zona(esto no tiene mucha importancia).Despues con otra funcion le muestro el estado de las localidades de esa zona.es decir una ristra de unos(1) que indican que la localidad esta libre,y le pregunto que localidad desea.Y aqui viene el problema:no se como hacer que el estado de esa localidad,de ese partido cambie,ademas de que al aforo le sume uno y a la recaudacion total le sume el precio dela entrada establecido al inicializar las localidades(esto no m da problemas).

Decir que lo esto haciendo con una lista que cada vez que cierro el rpograma es volcada a un fichero.Por supuesto cuando lo abro este lo vuelvo al a lista claro.
Os dejo lo que tengo hecho a ver si alguno puede echarme una mano xq stoy ahi atascado:emo: :

Parte del main:

/*variables*/
nodo *plistapartidos=NULL*p=NULL;
Tpartido partido;

/*Aqui se supone que ya tengo elejido el partido y el puntero a él es p*/
case 1://caso 1 venta de entradas lateral este
{
printf("\n\nVENTA DE ENTRADAS LATERAL ESTE");
zona=1;//asignacion de valor a la variable
mostrar_estado_ventas(p,zona);//llamada a funcion mostrar_estado_ventas
do//repetir
{
printf("\n\nSeleccione la localidad que desea: ");
scanf("%d",&a);
}while(a<1 || a>100);//validacion de datos y fin repetir
actualizar(partido,a);
actualizar_localidades(p,partido);//llamada a funcion actualizar localidades
getch();//parada
break;//fin caso 1
}

/*funciones que tengo echas*/

void actualizar(Tpartido partido,int i)
{
i--;
partido.localidad[i].estado=0;
partido.aforo=partido.aforo+1;
partido.recaudacion=partido.recaudacion+partido.lo calidad[i].precio;
printf("\n\nEl precio es: %.2f",partido.localidad[i].precio);
}

void actualizar_localidades(nodo* (&Plista),Tpartido partido)
{
Plista->info3=partido;
}Igual estoy haciendo alguna burrada pero es que estoy ya saturao y no encuentro ocmo hacerlo...

Xuanín
04-06-2008, 18:55:50
echale un vistazo al paso de parámetros y las diferencias entre variables de pila y las del heap

Kayros
04-06-2008, 18:55:53
No me lo he leido entero (que me tengo que ir rapido, luego cuando vuelva me lo leo como dios manda), pero asi a bote pronto, para rellenar las localidades, se me ocurre lo siguiente:
Declara un vector de tipo Tlocalidades e inicializa el estado a 0. Cuando quieras vender la localidad, lo cambias a 1 y listo. Si necesitas que sea por partido, en lugar de un vector, le pones una matriz donde las filas sean partidos y las columnas, localidades. Y despues lo de sumar el precio, es cuestion de llevar un total e ir acumulando ahi. Y lo del aforo, igual. Un total con el aforo maximo, e ir restando a medida que vayas vendiendo localidades, hasta llegar a 0. (insisto, si estas 2 ultimas cosas tambien las necesitas por partido, un vector con un elemento por cada partido, y a correr.)

Todas estas cosas, si vas a usar funciones, tienes que mirar si las vas a mandar por valor y recibirlas en una variable o por referencia directamente.

Xuanín
04-06-2008, 19:05:06
Veamos, en C no existe el paso por referencia. lo q se ha de hacer es declarar el prototipo de la función con punteros y a la hora de llamar a dicha función, pasarle la dirección.

Ejemplo:

esta funcion retorna b+1 y modifica el valor de b
int f (int *b)
{
(*b) ++;
return *b;
}
(se llama f(&b))

esta funcion retorna b+1 y NO modifica el valor de b
int f (int b)
{
b ++;
return b;
}
(se llama f(b))

Umec
04-06-2008, 19:06:45
Las localidades las tengo rellenas es decir inicializadas...cada una con su precio su zona..y todas con el estado=1,es decir,libre.

El tema es cambiarlo cuando vendo la entrada.Tengo que cambiar el valor estado de la posicion del array localidades de la localidad y el partido exacto.El partido en teoria se lo paso con el puntero y la posicion del array(que es la localidad) lo recorro con i.Pero ahi me casca.

Xuanín
04-06-2008, 19:16:59
¿dónde haces el malloc de PLista?

Umec
04-06-2008, 19:20:19
En otra funcion donde voy rellenando los partidos con rival,jornada...etc.Tengo que hacer otro malloc al modificarlo otra vez???pero es que solo quiero modificar esos datos yla reserva de memorai ya debe estar hecha ay que todos estan inicializados:el estado a 1 y el aforo y la recaudacion a 0)

Xuanín
04-06-2008, 19:25:19
No, no hace falta, era q no lo veía, el caso es que si tu tienes un vector dinamico de nodos como PLista y unos de sus campos es una estructura de tipo partido y esta a su vez tiene como campo un vector estatico para las localidad, pues hay q tener cuidado. primero, creo q en la función actualizar no modificas los partidos. segundo, en la función actualizar_localidades haces una asignación tal cual. quizas funcione para los campos simples, pero está claro que no te va a guardar el vector localidades.

Xuanín
04-06-2008, 19:27:10
Veamos, en C no existe el paso por referencia. lo q se ha de hacer es declarar el prototipo de la función con punteros y a la hora de llamar a dicha función, pasarle la dirección.

Ejemplo:

esta funcion retorna b+1 y modifica el valor de b
int f (int *b)
{
(*b) ++;
return *b;
}
(se llama f(&b))

esta funcion retorna b+1 y NO modifica el valor de b
int f (int b)
{
b ++;
return b;
}
(se llama f(b))

no sé si te has mirado esto...

Umec
04-06-2008, 19:35:34
No, no hace falta, era q no lo veía, el caso es que si tu tienes un vector dinamico de nodos como PLista y unos de sus campos es una estructura de tipo partido y esta a su vez tiene como campo un vector estatico para las localidad, pues hay q tener cuidado. primero, creo q en la función actualizar no modificas los partidos. segundo, en la función actualizar_localidades haces una asignación tal cual. quizas funcione para los campos simples, pero está claro que no te va a guardar el vector localidades.

Pufff sq nose tonces como peudo hacerlo...en actualizar modifico los datos de la estructura...que despues se la paso a actualizar_localidades junto con el puntero del partido al que quiero asignarselo.

no sé si te has mirado esto...
Si l ohe mirado pero no se que quieres decirme realmente con eso...en el caso del que hablo:sudor:


jeje igual es que estoy demasiado verde

Xuanín
04-06-2008, 19:41:22
El caso es que si tu asignas a pelo una estructura, el = te va a asignar correctamente los campos simples, digamoslo así. pero tu no puedes igualar a pelo dos vectores. tienes que ir recorriéndolos o hacer un memcpy (asegurandote de que lo haces con posiciones de memoria validas)

Xuanín
04-06-2008, 19:53:34
estoy intentando buscar un compilador de esto. si me pasas el código puedo echarle un vis y te hago unos comentarios

Xuanín
04-06-2008, 20:01:17
De todas formas, esta declaración me deja patidifuso /*variables*/
nodo *plistapartidos=NULL*p=NULL;
Tpartido partido;

Kayros
04-06-2008, 20:01:50
Veamos, en C no existe el paso por referencia. lo q se ha de hacer es declarar el prototipo de la función con punteros y a la hora de llamar a dicha función, pasarle la dirección.

Ejemplo:

esta funcion retorna b+1 y modifica el valor de b
int f (int *b)
{
(*b) ++;
return *b;
}
(se llama f(&b))

esta funcion retorna b+1 y NO modifica el valor de b
int f (int b)
{
b ++;
return b;
}
(se llama f(b))

Hombre, pasarlo como puntero a una función es pasarlo por referencia :p (el paso por referencia que existe en C)

estoy intentando buscar un compilador de esto. si me pasas el código puedo echarle un vis y te hago unos comentarios

Bajate el Mingw de parinyasoft. Una maravilla (y es GNU creo... libre en cualquier caso).

Xuanín
04-06-2008, 20:07:10
Hombre, pasarlo como puntero a una función es pasarlo por referencia :p (el paso por referencia que existe en C).
Es un apaño, no es el "paso por referencia que existe en C", porque en C no existe paso por referencia al estilo de C++.

Voy a ver el mingw ese..

titolancreo
04-06-2008, 20:08:15
Veamos, en C no existe el paso por referencia. lo q se ha de hacer es declarar el prototipo de la función con punteros y a la hora de llamar a dicha función, pasarle la dirección.

Ejemplo:

esta funcion retorna b+1 y modifica el valor de b
int f (int *b)
{
(*b) ++;
return *b;
}
(se llama f(&b))

esta funcion retorna b+1 y NO modifica el valor de b
int f (int b)
{
b ++;
return b;
}
(se llama f(b))

Hombre yo a la definicion esa lo llamo paso por referencia, es decir, cuando mandas la direccion de memoria y trabajas sobre ella.

Con eso se refiere a que en una funcion modifica (pone el * antes de la funcion) y en la otra no (pone return b, sin el *), yo creo que tambien puede ser ese el problema, que a lo mejor te has colado a la hora de modificar el puntero en una de tus funciones ya que tu ves que estas modificando, pero si no pones el * por ejemplo no cambias nada en realidad y por lo tanto si la mision de la funcion es editar un valor que pasas del main, no te va a hacer nada, ya que al volver, el valor no ha sido modificado.

De todas formas no se con que compilador lo estaras haciendo pero supongo que tendra una herramienta para que vaya ejecutando cada cosa con un click tuyo (un Debugger), pon las variables que te interesen y vete mirando donde recibes un valor que no tenia que ser, y seguro que lo descubres. De todas formas prueba a mirar todas las funciones otra vez y fijate cuando quieres que un valor (no puntero) quieras que este modificado en el main a travaes de la funcion a la que llamas, y si eso lo hace bien, al igual que lo que te dice de los vectores



PD: un consejo tio, pasale un corrector que si tienes que entregarlo te van a meter un cate solo por esto jejejejeje

/*Aqui se supone que ya tengo elegido el partido y el puntero a él es p*/


/*funciones que tengo hechas*/ jejeje

Kayros
04-06-2008, 20:08:56
Te dejo el enlace a la descarga aqui (http://www.simtel.net/product.php%5Bid%5D74843%5Bsekid%5D0%5BSiteID%5Dsi mtel.net)

titolancreo
04-06-2008, 20:10:28
El MinGW esta bien, es el que usamos en la uni y va bastante bien, lo unico que despues de crear el proyecto, le das a crear nuevo y tienes que ponerle la extension.c, porque sino te lo guarda como .cpp

Umec
04-06-2008, 20:12:44
De todas formas, esta declaración me deja patidifuso /*variables*/
nodo *plistapartidos=NULL,*p=NULL;
Tpartido partido;
XD XD faltaba una coma

aqui (http://www.megaupload.com/es/?d=GT9SJ1Q8) te dejo el codigo...ya veras q desastre XD XD

x7iBiT
04-06-2008, 20:13:24
Las localidades las tengo rellenas es decir inicializadas...cada una con su precio su zona..y todas con el estado=1,es decir,libre.

El tema es cambiarlo cuando vendo la entrada.Tengo que cambiar el valor estado de la posicion del array localidades de la localidad y el partido exacto.El partido en teoria se lo paso con el puntero y la posicion del array(que es la localidad) lo recorro con i.Pero ahi me casca.

Es que si te casca ahí, es porque probablemente estás intentando acceder a una zona de memoria que no tienes reservada. Las localidades son estáticas (array de 280) así que el problema tiene que estar en los punteros de los nodos, o bien el el malloc que haces del nodo.

De todas formas, con el código que has puesto, no accedería a la localidad escogida para ver si efectivamente está libre o no (simplemente la machaca poniendola como cogida y punto). Yo creo que es mejor que accedas directamente a ella, y en el caso de que esté libre pues la pone como "cogida", y en el caso de que ya esté cogida pues tendría que mostrarte que esa localidad ya estaba ocupada y que elijas otra.

titolancreo
04-06-2008, 20:19:51
El archivo ese le tienes .cpp, es decir en C++

Umec
04-06-2008, 20:21:09
.
De todas formas, con el código que has puesto, no accedería a la localidad escogida para ver si efectivamente está libre o no (simplemente la machaca poniendola como cogida y punto). Yo creo que es mejor que accedas directamente a ella, y en el caso de que esté libre pues la pone como "cogida", y en el caso de que ya esté cogida pues tendría que mostrarte que esa localidad ya estaba ocupada y que elijas otra.
Eso es exactamente lo que quiero hacer XD pero no se como hacerlo...yo pensaba que al pasarle el puntero del partido(previamente seleccionado por el usuario y buscado con otra funcion"),y la posicion dela localidad en el array(que tambien la pone el usuario) accedia directamente a la parte de la estructura que queria:?

Umec
04-06-2008, 20:24:07
El archivo ese le tienes .cpp, es decir en C++
xq trbajo con borland c++...pero segun mi profesor es C XD ademas q no tengo nada de objetos,ni herencias,ni movidas de esas

x7iBiT
04-06-2008, 20:27:20
Eso es porque C está contenido dentro de C++.

PD: Voy a echarle un ojo al código a ver...


EDITO: BUffffffffffffffffff, lo acabo de compilar con el GCC de Linux y me da 295 errores (sobre todo en los punteros).

Umec
04-06-2008, 20:46:15
Eso es porque C está contenido dentro de C++.

PD: Voy a echarle un ojo al código a ver...


EDITO: BUffffffffffffffffff, lo acabo de compilar con el GCC de Linux y me da 295 errores (sobre todo en los punteros).
No jodas pos a mi no m da ningun error:?

Xuanín
04-06-2008, 20:54:20
Me he perdido en una cosa. Si tu tienes un puntero a nodo plistaabonados y luego pasas a la función &plistaabonados, ya no le estas pasando un puntero a nodo. en realidad le estas pasando la dirección de memoria de un puntero a nodo.

Umec
04-06-2008, 21:03:58
Me he perdido en una cosa. Si tu tienes un puntero a nodo plistaabonados y luego pasas a la función &plistaabonados, ya no le estas pasando un puntero a nodo. en realidad le estas pasando la dirección de memoria de un puntero a nodo.

No se trnco...como ya no sabia tire de libro...y lo puse asi...xq no sabia ni que poner...

Pero na..no os preocupeis si no lo entendeis...q sq no tengo ni idea de como hacerlo y ya he peusto de todo y mas ahi al adesesperada.Ya si eso mñana le preguntare al profesor a ver como puedo hacerlo...

gracias de toas formas a todos!!!!!!:amor::alegre:

Xuanín
04-06-2008, 21:10:08
es q ahora no tengo tiempo, mañana le dedicaré más si puedo. y si no xzibit seguro q lo saca antes si esta libre :genial:

x7iBiT
04-06-2008, 22:54:12
Bufff yo estoy hasta el cuello también. Tengo que exponer mañana un trabajo y me lo tengo que aprender al dedillo, y dar con el problema lleva su tiempo, y más con punteros de por medio (es en donde te estás haciendo el gran lío, por lo poco que he visto).

De todas formas muchos de esos errores que me daban al compilar son más que lógicos, ya que son por funciones propias de Borland que no existen en un C convencional.

Umec
05-06-2008, 14:48:04
Chicoooooooooos al finla mi profesor ma echao un cable y ya lo he conseguio!!

La funcion es tal que asi:

void actualizar_localidades(nodo* (Plista),Tpartido partido,int i)
{
i--;
Plista->info3.localidad[i].estado=0;
Plista->info3.aforo=Plista->info3.aforo+1;
Plista->info3.recaudacion=Plista->info3.recaudacion+Plista->info3.localidad[i].precio;
printf("\n\nEl precio es: %.2f",Plista->info3.localidad[i].precio);
}

bien ya me tira casi todo!! tengo que validar algunas cosas y acer unas funciones que me faltan!! :alegre::alegre::alegre::alegre:

gracias a todoooooooooooooooooos!!!

Xuanín
05-06-2008, 14:55:29
Chicoooooooooos al finla mi profesor ma echao un cable y ya lo he conseguio!!

La funcion es tal que asi:

void actualizar_localidades(nodo* (Plista),Tpartido partido,int i)
{
i--;
Plista->info3.localidad[i].estado=0;
Plista->info3.aforo=Plista->info3.aforo+1;
Plista->info3.recaudacion=Plista->info3.recaudacion+Plista->info3.localidad[i].precio;
printf("\n\nEl precio es: %.2f",Plista->info3.localidad[i].precio);
}

bien ya me tira casi todo!! tengo que validar algunas cosas y acer unas funciones que me faltan!! :alegre::alegre::alegre::alegre:

gracias a todoooooooooooooooooos!!!

Ya te decía yo que ese paso de nodo *(&Plista) era un desfase. pa lo q quieras andaremos por aquí.