Ayuda con programación en C [PROBLEM en pag 2]

Buenas, estoy con un programa con estructuras de C, con peliculas y actores.


Tengo una opcion que es borrar una pelicula(con todos sus actores) y otra opcion que es borrar UN actor.

Mi pregunta es.... puedo hacer las dos cosas en una misma funcion?? O tengo que hacer una funcion para cada cosa?



Porque estoy pensando y para borrar todos los actores utilizo un "for" si o si, pero para un actor le tengo que pasar la posicion... es inviable hacer una función que englobe a las 2 opciones, no?
Do one thing and do it well (Filosofía de UNIX).

Cada función debería hacer una sola cosa.
Es perfectamente viable hacer una función que englobe dos funcionalidades, pero lo más recomendable, y más si estás empezando, es hacer que cada función haga una sola tarea. Puedes por ejemplo hacer una función que borre un actor y luego una función que borre la película, que llame a la función de borrar actor en cada actor de la película.

Si aún así quieres hacer una función que englobe varias opciones, incluye un parámetro opción y luego un if o un switch/case dentro de la función.
Korso10 escribió:Es perfectamente viable hacer una función que englobe dos funcionalidades, pero lo más recomendable, y más si estás empezando, es hacer que cada función haga una sola tarea. Puedes por ejemplo hacer una función que borre un actor y luego una función que borre la película, que llame a la función de borrar actor en cada actor de la película.

Si aún así quieres hacer una función que englobe varias opciones, incluye un parámetro opción y luego un if o un switch/case dentro de la función.


Esque estoy haciendo un trabajo y me piden como importante que simplifique codigo ,que ponga cosas en una funcion que sirva para varias y tal y no se como se haria borrar varios actores y borrar solo 1 actor en una sola funcion.

Cuando borro varios actores le paso todos los actores de golpe, pero cuando quiero borrar 1 actor le estoy pasando la posicion de ese actor.


Mi código en borrar todos los actores es:

void borraractores(struct peliculas *pelicula, int celda){
   int e;
   char resp;


         
         for(e=0;e<5;e++){

            pelicula[celda].act[e].nombre[0]='0';
            pelicula[celda].act[e].edad=0;
            pelicula[celda].act[e].sexo[0]='0';
               }
}



Pero para borrar un actor...


void borraractor(struct actores *act, int celda2){
   char resp;



   printf("\n¿Quieres borrar el actor?[S/N]: ");
   fflush(stdin);
   scanf("%c", &resp);
   
   

   
         if(resp=='s'){


            act[celdadelactor].nombre[0]='0';
            act[celdadelactor].edad=0;
            act[celdadelactor].sexo[0]='0';
            }
         
}





En un sitio le paso la estructura de peliculas (porque quiero borrar todo), en el otro lado le paso la estructura de actores con la variable 'celdadelapeli' que es el actor que quiero borrar. Como se haria en una funcion?
Esto es a gusto del programador. Yo lo haría en dos funciones, una para cada cosa.

Si se hace todo en la misma función,, si en el futuro quieres borrar un actor o una película, te tendrías que crear otra función copiando parte del código de la función, y eso es duplicar código a lo tonto.

Si quieres borrar tanto un actor como una película, haces una llamada a cada una de las funciones.
Me uno al club de para cada tarea un función.
CP3 escribió:
for(e=0;e<5;e++){

No sé en C (supongo que también), pero esto en Java tendría todas las papeletas de darte un IndexOutOfBoundsException. ¿Siempre hay cinco y sólo cinco? Si hay menos, te va a cascar, si hay más no se van a borrar todos, y si siempre hay cinco tampoco lo haría así.
Bueno pues lo dejo en dos funciones, espero que no me digan que esta mal :-?

Gracias.
Lo más correcto es hacerlo en 2....
Normalmente cuando piden que simplifiques código y que lo reutilices, te piden que cada función haga una cosa, pero si vas a borrar todos los actores, llamas a la función de borrar un actor n veces, como te han dicho más arriba ;).

Me uno también a lo que te dice _Locke_, cuidado con el valor 5 hardcodeado ahí :).

Salu2!!!
CP3 escribió:Bueno pues lo dejo en dos funciones, espero que no me digan que esta mal :-?

Gracias.

No puede decirte que está mal, es una decisión de diseño que en última instancia es decisión del programador. Yo soy de la opinión del resto de eolianos: una función -> una tarea. El código es siempre más claro de este modo.
Una función para cada tarea, creo que estamos todos a favor XD
amchacon escribió:Do one thing and do it well (Filosofía de UNIX).

Cada función debería hacer una sola cosa.

Korso10 escribió:Es perfectamente viable hacer una función que englobe dos funcionalidades, pero lo más recomendable, y más si estás empezando, es hacer que cada función haga una sola tarea. Puedes por ejemplo hacer una función que borre un actor y luego una función que borre la película, que llame a la función de borrar actor en cada actor de la película.

Fin del hilo
Aunque estás en C y ahí, a priori, no hay programación orientada a objetos, estás en un caso donde va muy bien pensarlo a través de este paradigma.

Si no entiendo mal, tendrás una lista de estructuras de tipo Película, y otra lista de tipo Actor. Una película está protagonizada por una lista de actores, ergo tendrás por ahí una lista de punteros de tipo Actor dentro de la estructura Película.

Son dos acciones distintas la de borrar una película, a la de borrar un actor. Si tienes que borrar una película, borras la estructura y se acabo. No hay necesidad de borrar las estructuras de actores.

Sin embargo, si tienes que borrar un actor, tienes que patearte todas las películas para borrar el actor en cada una de ellas (con la consecuencia que tienes que redimensionar la lista), por eso de mantener la consistencia de la información que tienes ahí y esas cosas.

Viéndolo de esta manera, ¿crees que deberías tener todo en una misma función?
Muchas gracias por vuestra ayuda.

Aqui traigo un error que me ha surgido de mientras que me respondiais en este rato. Y me estoy volviendo MUY loco llegando ya a la desesperación, agradeceria que me ayudaseis de nuevo...




En la aplicación esta tengo una opcion que muestra una pelicula con sus actores en pantalla.

1.Le pido al usuario la pelicula, llamo a una funcion que busca en el aray de peliculas cual es, y retorno la posicion.
2.Seguidamente llamo a la funcion que muestra la informacion por pantalla y le paso el array con la posición.

Pues bien... introduzco 2 peliculas y la primera me la muestra bien, pero la segunda me aparece vacia, he estado debugeando y mirando pero no encuentro el error...

El codigo es este:

OPCION DE MOSTRAR PELICULA
case 3:
      printf("\nIntroduce el titulo de la pelicula: ");
      fflush(stdin);
      gets(peli);

      celda = buscarpeli(pelicula, peli);


      if(celda!= -1){   

         mostrarpeli(&pelicula[celda], celda);
         
      }else{
         printf("\nNo se encuentra la pelicula");
      }

      

      break;



FUNCION DE MOSTRAR PELICULA
void mostrarpeli(struct peliculas pelicula[], int celda){
   int e;
   


         printf("\nPELICULA");
         
         
         if(pelicula[celda].calificacion!=0){
         printf("\n Titulo: %s - Director: %s - Calificacion: %d", pelicula[celda].titulo, pelicula[celda].director, pelicula[celda].calificacion);
         }
         
         printf("\nACTORES");
         for(e=0;e<5;e++){
            
         if(pelicula[celda].act[e].edad!=0){
            
            printf("\n Nombre: %s - Edad: %d - Sexo: %s", pelicula[celda].act[e].nombre, pelicula[celda].act[e].edad, pelicula[celda].act[e].sexo);
         
               }
            }
         

      }




Imaginad que la primera pelicula se llama "a", el director es "a" y la calificacion es "1". LA segunda pelicula es "b", el director es "b" y la calificacion es "2".


Pues bien en el debug de la "a" me sale esto:

Imagen

La primera linea quiere decir la pelicula que le he pasado y la segunda el contenido de pelicula[celda] (celda vale 0), la primera pelicula del array en la posicion 0).


Pero en el de la "b" esto:

Imagen

La primera linea me dice que le paso bien la pelicula... PERO PORQUE LUEGO ME SALE VACIA??? La posición(celda) esta bien porque sino no me pondria en la primera linea los datos bien, es la "1", ya que es la segunda pelicula del array pero no consigo entender porque me sale vacia esa pelicula.








Si leeis esto, muchas gracias por vuestra lectura, a veces la programación me desespera mucho no... MUCHÍSIMO.
La mayoría de estos errores extraños estan ocasionados por un despiste muy tonto.

No hay suficiente información para concluir nada, no sabemos como funciona añadir película.
amchacon escribió:La mayoría de estos errores extraños estan ocasionados por un despiste muy tonto.

No hay suficiente información para concluir nada, no sabemos como funciona añadir película.



OPCION DE AÑADIR PELICULA

case 1:
      celda = celdalibre(pelicula);
      if(celda!= -1){
         introducirpel(&pelicula[celda]);
         printf("\n Se ha introducido la pelicula correctamente");


      }else{
         printf("\nNo hay espacio libre para introducir peliculas");
      }
      break;





FUNCION DE INTRODUCIR PELICULA

void introducirpel(struct peliculas *pelicula){


   printf("Titulo de la pelicula: ");
   fflush(stdin);
   gets(pelicula->titulo);

   printf("Nombre del director: ");
   fflush(stdin);
   gets(pelicula->director);

   do{
   printf("Calificacion: ");
   fflush(stdin);
   scanf("%d", &pelicula->calificacion);
   }while(pelicula->calificacion<1 || pelicula->calificacion>5);
}
Hace años que no toco C... pero diría que el error está cuando pasas la dirección de memoria a mostrarpeli. Ahí ya estas pasando la dirección de la película, y en la función la tratas como si dentro de la película que vas a mostrar, hubiera otra película.
Rozan escribió:Hace años que no toco C... pero diría que el error está cuando pasas la dirección de memoria a mostrarpeli. Ahí ya estas pasando la dirección de la película, y en la función la tratas como si dentro de la película que vas a mostrar, hubiera otra película.

Entonces como le muestro el nombre de la peli por ejemplo??

Si "pelicula[celda].titulo" no es?
CP3 escribió:
Rozan escribió:Hace años que no toco C... pero diría que el error está cuando pasas la dirección de memoria a mostrarpeli. Ahí ya estas pasando la dirección de la película, y en la función la tratas como si dentro de la película que vas a mostrar, hubiera otra película.

Entonces como le muestro el nombre de la peli por ejemplo??

Si "pelicula[celda].titulo" no es?


Diría que así funcionaría... pero como te digo, hace años que no toco C, y puedo estar equivocado. Pero por probar.

void mostrarpeli(struct peliculas pelicula, int celda){
   int e;
   


         printf("\nPELICULA");
         
         
         if(pelicula.calificacion!=0){
         printf("\n Titulo: %s - Director: %s - Calificacion: %d", pelicula.titulo, pelicula.director, pelicula.calificacion);
         }
         
         printf("\nACTORES");
         for(e=0;e<5;e++){
           
         if(pelicula.act[e].edad!=0){
           
            printf("\n Nombre: %s - Edad: %d - Sexo: %s", pelicula.act[e].nombre, pelicula.act[e].edad, pelicula.act[e].sexo);
         
               }
            }
         

      }
Rozan escribió:
CP3 escribió:
Rozan escribió:Hace años que no toco C... pero diría que el error está cuando pasas la dirección de memoria a mostrarpeli. Ahí ya estas pasando la dirección de la película, y en la función la tratas como si dentro de la película que vas a mostrar, hubiera otra película.

Entonces como le muestro el nombre de la peli por ejemplo??

Si "pelicula[celda].titulo" no es?


Diría que así funcionaría... pero como te digo, hace años que no toco C, y puedo estar equivocado. Pero por probar.

void mostrarpeli(struct peliculas pelicula, int celda){
   int e;
   


         printf("\nPELICULA");
         
         
         if(pelicula.calificacion!=0){
         printf("\n Titulo: %s - Director: %s - Calificacion: %d", pelicula.titulo, pelicula.director, pelicula.calificacion);
         }
         
         printf("\nACTORES");
         for(e=0;e<5;e++){
           
         if(pelicula.act[e].edad!=0){
           
            printf("\n Nombre: %s - Edad: %d - Sexo: %s", pelicula.act[e].nombre, pelicula.act[e].edad, pelicula.act[e].sexo);
         
               }
            }
         

      }



Pues si, asi si funciona pero a veces hago cosas que funcionan y la profe me dice que no, y no se si este será el caso, aunque como no se otra solucion lo dejaré asi, a ver que dice... muchas gracias, sea o no al menos lo he podido arreglar aunque no sepa si esta al 100% bien.
CP3 escribió:
Pues si, asi si funciona pero a veces hago cosas que funcionan y la profe me dice que no, y no se si este será el caso, aunque como no se otra solucion lo dejaré asi, a ver que dice... muchas gracias, sea o no al menos lo he podido arreglar aunque no sepa si esta al 100% bien.


Eso nos pasaba a todos... hacer una cosa y que te diga el profesor de turno que así no, porque de la manera que la hace él es más eficiente y demás rollos.

PD: De nada... xD
Rozan escribió:
CP3 escribió:
Pues si, asi si funciona pero a veces hago cosas que funcionan y la profe me dice que no, y no se si este será el caso, aunque como no se otra solucion lo dejaré asi, a ver que dice... muchas gracias, sea o no al menos lo he podido arreglar aunque no sepa si esta al 100% bien.


Eso nos pasaba a todos... hacer una cosa y que te diga el profesor de turno que así no, porque de la manera que la hace él es más eficiente y demás rollos.

PD: De nada... xD


Ya te digo, cuando hago algo que me ha costado y veo que funciona y me digan "no asi no es" y me queda una cara de tonto...
La segunda te sale vacía porque el puntero "película" apunta a la ultima película del array, por lo que "pelicula[celda]" esta apuntando a una dirección de la memoria fuera del array de películas.

El fallo que estas cometiendo es que estas llamando a la función mostrarpelicula pasándole un puntero de la película que quieres mostrar y su indice, cuando solo necesitas una de las dos cosas (o le pasas el puntero de la peli a mostrar, o un puntero a la primera peli del array y el índice de la peli a mostrar).

Otra opción, aunque no es la mas eficiente, es la que te han puesto (aunque sobra el parametro del índice). En ella estas pasando la película por valor en vez de pasar su direccion, por lo que cada vez que llames a esta función se va a copiar la estructura película entera, mientras que si pasas un puntero (o una referencia) se copia solo su dirección.
kbks escribió:La segunda te sale vacía porque el puntero "película" apunta a la ultima película del array, por lo que "pelicula[celda]" esta apuntando a una dirección de la memoria fuera del array de películas.

El fallo que estas cometiendo es que estas llamando a la función mostrarpelicula pasándole un puntero de la película que quieres mostrar y su indice, cuando solo necesitas una de las dos cosas (o le pasas el puntero de la peli a mostrar, o un puntero a la primera peli del array y el índice de la peli a mostrar).

Otra opción, aunque no es la mas eficiente, es la que te han puesto (aunque sobra el parametro del índice). En ella estas pasando la película por valor en vez de pasar su direccion, por lo que cada vez que llames a esta función se va a copiar la estructura película entera, mientras que si pasas un puntero (o una referencia) se copia solo su dirección.



Gracias por tu respuesta, la verdad es que me estoy haciendo un lio muy grande.

Exactamente como podria pasarle solo la pelicula que quiero mostrar??

Pensaba que como lo hacia estaba bien.


como dije tengo esto al llamar a mostrar la pelicula:

mostrarpeli(&pelicula[celda], celda);


void mostrarpeli(struct peliculas pelicula[], int celda){



Y gracias
Sin entrar en temas mas escabrosos (referencias, const, etc...) deberías hacerlo así:

La llamada:
mostrarpeli(&pelicula[celda]);


Y la función:
void mostrarpeli(struct pelicula* pPelicula);


Es decir, pasar solo el puntero a la película que quieres mostrar. ¿Para que necesitas el índice de la pelicula si ya estas pasando su dirección? Al final lo que tu estas haciendo es acceder a la película en la posición "celda + celda", por lo que te sales del array cada dos por tres.

Respecto a la solución que te han dado funcionar funciona, pero estas creando una copia innecesaria de la película cada vez que quieres mostrarla.

Lo que necesitas hacer antes de nada es entender como funcionan los punteros y que es lo que realmente estas haciendo en cada función cuando pasas los parámetros.
25 respuestas