[ Foro de Pascal ]

últimos ajustes programa PASCAL

06-May-2011 08:57
Manuel Molina
3 Respuestas

Bueno más o menos he afinado el programa. Pero como vereís ahora cuando lo ejecuto en la opcion de modficar datos no lo hace, ni en dar de baja y lo curioso es que no puedo dar nada más que de alta un libro.

Me podeis decir que es lo que me falta por poner?

PROGRAM Bibliotecas;

(*CONSTANTES DEL PROGRAMA, EL TAMAÑO MÁXIMO DE LA LÍNEA Y DE LA BIBLIOTECA*)
CONST
(*Tamaño de la biblioteca*)
  TAMBIBLIOTECA = 5;  
(*Tamaño máximo de la línea*)  
  TAMMAXI     = 25;
 
TYPE
(* REGISTRO ANIDADO QUE DEFINE LAS CARACTERÍSTICAS DE CADA LIBRO *)
  (* Datos del Préstamo *)
Tprestado = record
nom_apellidos : string [TAMMAXI];
email         : string [TAMMAXI];
fecha  : integer;
codigo_libro  : integer;
end;

(* Datos del libro *)
Tlibro = record
datos  : Tprestado;
codigo : integer;
titulo : string [TAMMAXI];
autor  : string [TAMMAXI];
tema   : string [TAMMAXI];
precio : integer;
alta   : Boolean;
activo : Boolean;
end;

(* -- TABLA SOBRE LA QUE VAMOS A TRABAJAR EN EL PROYECTO BIBLIOTECA --*)
Tbiblioteca = array[1..TAMBIBLIOTECA] of Tlibro;
(* -- FICHERO SOBRE LA QUE VAMOS A ALMACENAR LOS DATOS DE LA BIBLIOTECA--*)
  Tfichero = file of Tlibro;

(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!! FUNCIONES Y PROCEDIMIENTOS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)

(* -- LEE DEL TECLADO TODA LA INFORMACIÓN DE UN LIBRO QUE SE LE PASA--*)

PROCEDURE lee_libro(var libro: Tlibro);

begin

writeln;
libro.alta:= true;  (*Siempre el alta de un libro es true*)
libro.activo:=false; (*Siempre el es false hasta que se modifique el libro *)
writeln('Codigo: ');
readln(libro.codigo);
writeln('Titulo: ');
readln(libro.titulo);
writeln('Autor: ');
readln(libro.autor);
writeln('Tema: ');
readln(libro.tema);
writeln('Precio: ');
readln(libro.precio);
writeln;

end;
(*--PARA BUSCAR POSICION LIBRE Y DAR ALTA UN LIBRO --*)
PROCEDURE alta_libro(VAR biblioteca: Tbiblioteca; longitud: integer);
(*variables para almacenar las búsquedas*)
var

encontrado : Boolean;
posicionlibre : integer;
fin : Boolean;
i: integer;

begin

encontrado:= false; (* Cuando sea TRUE es que he encontrado la posición *)
posicionlibre:= 1; (* Empiezo a buscar por la uno *)
i:= 1;  (* Para ir recorriendo la tabla *)
fin:= false; (* He llegado al final de la tabla *)

for i:= 1 to longitud do

  begin

While(encontrado = false) AND (fin = false) do (*aplicamos bucle mientras las condicienes de encontrado y fin sea false *)

if biblioteca[i].alta = false then begin (*Si alta es false y encontrado es verdadero obtenemos una posición libre*)
encontrado := true;
posicionlibre := i;
end

else

if i <> TAMBIBLIOTECA then begin  (*sumamos 1 posición a la posición libre*)
posicionlibre:= posicionlibre + 1;
end

else
 
fin:= true;
end;

begin

if fin = true then   (* Se nos indica cuando no tenemos más posiciones libres en la biblioteca *)
writeln(' No hay sitio en la tabla para los libros');
if encontrado = true then
begin
lee_libro(biblioteca[posicionlibre]);
writeln('Se ha guardado el libro en la posicion',posicionlibre);
end;
end;

end;

(* PRESENTAR LISTADOS DE LA BIBLIOTECA *)
PROCEDURE imprime_libro(libro: Tlibro);  

begin
                                       
writeln('--------------------------------------');
writeln('----------LISTADO POR LIBRO-----------');
writeln('--------------------------------------');
writeln('alta : ', libro.alta);
writeln('Prestado: ', libro.activo);
writeln('Codigo : ', libro.codigo);
writeln('Titulo : ', libro.titulo);
writeln('Autor : ' , libro.autor);
writeln('Tema : ', libro.tema);
writeln('Precio : ', libro.precio);
       writeln;
writeln('--------------------------------------');

end;
(* PROCEDIMIENTO QUE NOS IMPRIME POR PANTALLA LOS DATOS DEL LIBRO *)
PROCEDURE imprime_biblioteca(biblioteca: Tbiblioteca; longitud: integer);

var

i: integer;

begin

for i:= 1 to longitud do

begin
if biblioteca[i].alta = true then  
imprime_libro(biblioteca[i]);
end;

end;

(* PROCEDIMIENTO PARA INTRODUCIR DATOS DE LOS PRESTAMOS*)
Procedure hacer_prestamo(Var biblioteca: Tbiblioteca; longitud: integer; buscado: integer);
Var
 i: integer;
Begin
 For i:= 1 To longitud Do
     Begin
     If biblioteca[i].codigo = buscado Then
       Begin
         {biblioteca[i].prestado := true;}
         writeln(' Introducir Nombre y Apellido: ');
         readln(biblioteca[i].datos.nom_apellidos);
         writeln(' Introducir Email:  ');
         readln(biblioteca[i].datos.email);
         writeln(' Introducir Fecha: ');
         readln(biblioteca[i].datos.fecha);
       End;
     End;
End;

(* PROCEDIMIENTO PARA IMPRESION DE PRESTAMOS*)
PROCEDURE imprime_prestamo(biblioteca: Tbiblioteca; longitud: integer);

var
i:integer;
begin
for i:= 1 to longitud do;
writeln('----------------------------------------');
writeln('-----LISTADO DE LIBROS PRESTADOS--------');
writeln('----------------------------------------');
Writeln('Nombre y Apellido: ', biblioteca[i].datos.nom_apellidos);
writeln('Email: ' , biblioteca[i].datos.email);
writeln('Fecha de prestamo: ' , biblioteca[i].datos.fecha);
writeln('Codigo Libro: ', biblioteca[i].datos.codigo_libro);
end;

(* PROCEDIMIENTO QUE NOS IMPREME POR PANTALLA EL PROCEDIMIENTO ANTERIOR *)
PROCEDURE imprime_prestados(biblioteca: Tbiblioteca; longitud: integer);

var

i:  integer;

begin

for i:= 1 to longitud do;

begin

writeln('----------------------------------------');
writeln('-----LISTADO DE LIBROS PRESTADOS--------');
writeln('----------------------------------------');
imprime_prestamo(biblioteca, TAMBIBLIOTECA);

end;

end;

(* -- CON ESTE PROCEDIMIENTO PRETENDO BUSCAR Y MODIFICAR SU ESTADO DE ALTA, BAJA --*)
PROCEDURE baja_modificacion(biblioteca: Tbiblioteca; longitud: integer; buscado: integer);

var

      i  : integer;
encontrado: Boolean;

begin
(* Variable encontrado siempre a false *)
encontrado:= false;

for i:= 1 to longitud do

begin

if biblioteca[i].codigo = buscado then begin (*Si el codigo de la biblioteca es igual al introducido se llama al procedimiento imprime_libro*)
imprime_libro(biblioteca[i]); (*Llamada al procedimiento*)
encontrado:= true;    (*Ponemos encontrado a true*)
biblioteca[i].alta:=false;
end;

end;

begin

if encontrado = false then begin (* Si  la busqueda anterior no se produce no lee la siguiente línea*)
writeln('Libro no encontrado');
end;

end;


end;
(* PROCEDIMIENTO PARA LA BUSQUEDA Y MODIFICACION DE DATOS*)
PROCEDURE modificacion(biblioteca: Tbiblioteca; longitud: integer; buscado: integer);
(*variables del buble de la tabla y encontrado*)
var
i  : integer;
encontrado: Boolean;

begin

encontrado:= false; (* Ponemos encontrado a false para procedes a la busqueda*)

for i:= 1 to longitud do

begin
(* if que nos permite buscar en la biblioteca un codigo introducido *)
if biblioteca[i].codigo = buscado then begin  
imprime_libro(biblioteca[i]);
encontrado:= true;
biblioteca[i].alta:=true;
end;
(* if que nos permite introducir datos nuevos sobre un mismo libro *)
if biblioteca[i].codigo = buscado then begin
writeln('Modificar Libro');
lee_libro(biblioteca[i]);
end;

end;

begin
(* if que nos indica cuando un codigo de libro no ha sido encontrado *)
if encontrado = false then begin
writeln('Libro no encontrado');
end;

end;


end;
(* PROCEDIMIENTO PARA LA IMPRESION POR PANTALLA DE LOS LIBROS *)
PROCEDURE imprime_libros(biblioteca: Tbiblioteca; longitud: integer);
(* variable del bucle de la biblioteca *)
var

i: integer;

begin

for i:= 1 to longitud do

begin
(* llamada al procedimiento *)
imprime_libro(biblioteca[i]);

end;

end;
(* FUNCION QUE DEVUELVE EL VALOR TOTAL DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION suma_coleccion(biblioteca: Tbiblioteca; longitud: integer): real;
(*variable del bucle de la biblioteca *)
var

i: integer;

begin

suma_coleccion:= 0;

for i:= 1 to longitud do

begin
if biblioteca[i].alta = true then
suma_coleccion:= suma_coleccion + biblioteca[i].precio; (*calculo donde sumamos todos libros de la biblioteca *)
end;

end;

(* FUNCIÓN QUE DEVUELVE VALOR MÁXIMO DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION Maximo(biblioteca: Tbiblioteca; longitud: integer): real;
(*variables del buble y para almacenar el maximo del precio*)
var

i: integer;
max: integer;

begin

max:= 0;

for i:= 1 to longitud do
begin
if biblioteca[i].alta = true then
if max < biblioteca[i].precio then   (*Calculo del maximo precio de la biblioteca *)
  max:= biblioteca[i].precio;
  Maximo:= max;
end;
end;

(* FUNCION QUE DEVUELVE VALOR MÍNIMO DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION Minimo(biblioteca: Tbiblioteca; longitud: integer): real;
(*variables del bucle de biblioteca y min para almacenar el mínimo*)
var
i: integer;
min: integer;

begin

min:= 0;

for i:= 1 to longitud do
Begin
if biblioteca[i].alta = true then
if min > biblioteca[i].precio then  (*Calculo del mínimo precio de la biblioteca*)
min:= biblioteca[i].precio;
Minimo:= min;
end;

end;

(* FUNCION QUE DEVUELVE EL VALOR MEDIO DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION Media(biblioteca: Tbiblioteca; longitud: integer): real;
(*Variables del bucle y suma_coleción*)
var

i: integer;
suma_coleccion: integer;

begin

suma_coleccion:= 0;

for i:= 1 to longitud do

begin
if biblioteca[i].alta = true then
suma_coleccion:= suma_coleccion + biblioteca[i].precio; (*calculo para averiguar la media del valor del precio de la biblioteca*)
Media:= suma_coleccion/(TAMBIBLIOTECA);

end;

end;
(* PROCEDIMIENTO DONDE ENGLOBA LAS 4 FUNCIONES DONDE SE PIDEN EL CÁLCULO DE VALORES DE LA BIBLIOTECA*)
Procedure Resultados( biblioteca: Tbiblioteca; longitud: integer);

Begin
writeln;
writeln(' Suma: ', Media(biblioteca, TAMBIBLIOTECA):0:1);
writeln(' Maximo:  ', Maximo(biblioteca, TAMBIBLIOTECA):0:1);
writeln(' Minimo:  ', Minimo(biblioteca, TAMBIBLIOTECA):0:1);
writeln(' Media: ', Media(biblioteca, TAMBIBLIOTECA):0:1);
writeln;
End;

(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!   FUNCIONES DE FICHERO  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)

(*-- ALMACENA DATOS LEIDOS DE UN FICHERO --*)
PROCEDURE graba_fichero(nombre: string; var biblioteca: Tbiblioteca; longitud: integer);
Var
 i : integer;
 fichero : Tfichero;
Begin
 assign(fichero, nombre);
rewrite(fichero);

for i:= 1 to longitud do
if(biblioteca[i].alta = true) then         (* DEBE DE GUARDAR SOLO LOS LIBROS QUE COMO ALTA SEA TRUE*)
write(fichero, biblioteca[i]);

close(fichero);
End;

(*-- LEE DATOS DEL FICHERO --*)
PROCEDURE lee_fichero(nombre: string; var biblioteca: Tbiblioteca; longitud: integer);

Var
 i : integer;
fichero : Tfichero;

Begin
 i := 0;

assign(fichero, nombre);
reset(fichero);

   while ( not(eof(fichero)) AND (i<TAMBIBLIOTECA) ) do begin
   i := i+1;
   read(fichero, biblioteca[i]);

end;

close(fichero);

End;

(*-- FUNCIÓN QUE PRESENTA MENÚ Y DEVUELVE OPCIÓN ELEGIDA --*)
FUNCTION Menu: INTEGER;
(*VARIABLE DE LAS DIFERENTES OPCIONES DEL MENÚ*)
VAR

opc: integer;

BEGIN
(*BUCLE*)
repeat
(* PRESENTACIÓN EN PANTALLA DEL MENÚ Y LAS OPCIONES A ELEGIR *)
writeln('-----------------------------');
writeln('MENU DE GESTION DE BIBLIOTECA');
writeln('-----------------------------');
writeln;
writeln('1. ALTA DE LIBRO');
writeln('2. BAJA DE LIBRO');
writeln('3. DATOS DE PRESTAMO');
writeln('4. MODIFICACION DE DATOS');
writeln('5. GUARDAR DATOS EN FICHEROS');
writeln('6. LECTURA DE DATOS DE FICHERO');
writeln;
writeln('***PRESENTACION DE LISTADO DE BIBLIOTECA***');
writeln;
writeln('7. LISTADO DE TODOS LOS LIBROS DE LA BIBLIOTECA');
writeln('8. LISTADO DE LIBROS PRESTADOS');
writeln('9. LISTADO DE PRECIOS MAXIMOS, MINIMOS, LA MEDIA Y EL VALOR TOTAL DE LA COLECCION');  

writeln('10. SALIR');
writeln('OPCION:  ');
readln(opc);
until ( (opc>=1) and (opc <=9)or(opc=10));

Menu := opc;
End;
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!       VARIABLES GLOBALES         !!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
VAR

biblioteca: Tbiblioteca; (*variable de registro*)
opc  : integer; (*variable de menú*)
nombre    : string; (*variable de utilización, guardar y leer de fichero*)
buscado   : integer; (*variable de procedimiento de busqueda*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!    PROGRAMA PRINCIPAL          !!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)  
BEGIN
(*Bucle*)
repeat

opc:= Menu;

case opc of

1: alta_libro(biblioteca, TAMBIBLIOTECA); (*llamada procedimiento para altas de libro*)
 
2: begin (*codigo para dar de baja un libro*)
writeln('Introduzca el nombre del fichero: ');
readln(nombre);
lee_fichero(nombre, biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
writeln('Introducir codigo: ');
readln(buscado);
baja_modificacion(biblioteca, TAMBIBLIOTECA, buscado); (*LLamada procedimiento*)
writeln('Cambiar estado del libro: ');
alta_libro(biblioteca, TAMBIBLIOTECA);
end;
3:  begin  (*codigo para introducir datos de prestamos de libros*)
writeln('Codigo de libro a prestar');
readln(buscado);
hacer_prestamo(biblioteca, TAMBIBLIOTECA, buscado);
end;
4: begin (*codigo para modificar datos de libro*)
writeln('Introduzca el nombre del fichero: ');
readln(nombre);
lee_fichero(nombre, biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
writeln('Introducir codigo: ');
readln(buscado);
modificacion(biblioteca, TAMBIBLIOTECA, buscado);(*LLamada procedimiento*)
end;

5: begin (*Codigo para grabar fichero*)
writeln('Introduzca el nombre del fichero de datos: ');
readln(nombre);
graba_fichero(nombre, biblioteca, TAMBIBLIOTECA);  (*LLamada procedimiento*)
  end;
6: begin (*Codigo para lectura de fichero*)
writeln('Introduzca el nombre del fichero: ');
readln(nombre);
lee_fichero(nombre, biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
imprime_biblioteca(biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
  end;
7: begin (*Codigo para la lectura de todos los libros*)
writeln('Introduzca el nombre del fichero: ');
readln(nombre);
lee_fichero(nombre, biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
imprime_biblioteca(biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
  end;

8: begin (*Codigo para listados de libros y datos prestados*)
writeln('Introduzca el nombre del fichero de prestamo: ');
readln(nombre);
lee_fichero(nombre, biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
imprime_prestados(biblioteca, TAMBIBLIOTECA); (*LLamada procedimiento*)
end;
9: begin (*codigo para sacar estadisticas del precio de los libros*)
writeln('Introduzca el nombre del fichero : ');
readln(nombre);
lee_fichero(nombre, biblioteca, TAMBIBLIOTECA); (*llamada procedimiento*)
writeln('--------------------------------------------------------------');
writeln('LISTADO DE PRECIOS MAXIMOS, MINIMOS, LA MEDIA Y EL VALOR TOTAL');
writeln('--------------------------------------------------------------');
Resultados(biblioteca, TAMBIBLIOTECA); (*Llamada a procedimiento resultados, donde he aprendido que cuando que creando este procedimiento si funciona,
pero si lo haces llamando a cada función pues no*)
      end;

 
end;
until(opc=10);


END.


14-May-2011 00:17
Nacho Cabanes (+83)

Por cierto, esta consulta se había quedado sin contestar...

Para descubrir problemas como estos, analiza el código con detenimiento o al menos pon varios "WriteLn" que te digan por dónde avanza el programa.

Si lo analizas con detalle, verás que puede fallar aquí:

While(encontrado = false) AND (fin = false) do
 ...
 else if i <> TAMBIBLIOTECA then
   posicionlibre:= posicionlibre + 1;
   else ...

Esa parte de las comprobaciones no cambia el valor de "encontrado" ni de "fin", así que es un buen candidato a no salir nunca del "while" y bloquear el programa.




Como alternativa, puedes poner varios WriteLn, y verás que se queda "atascado" en "Sumamos 1", como era de esperar.

(*--PARA BUSCAR POSICION LIBRE Y DAR ALTA UN LIBRO --*)
PROCEDURE alta_libro(VAR biblioteca: Tbiblioteca; longitud: integer);
(*variables para almacenar las búsquedas*)
var
   encontrado : Boolean;
   posicionlibre : integer;
   fin : Boolean;
   i: integer;

begin
encontrado:= false; (* Cuando sea TRUE es que he encontrado la posición *)
posicionlibre:= 1; (* Empiezo a buscar por la uno *)
i:= 1;  (* Para ir recorriendo la tabla *)
fin:= false; (* He llegado al final de la tabla *)
writeln('Empezando alta...');
for i:= 1 to longitud do
       begin
       writeln('Revisando ficha ',i);
       While(encontrado = false) AND (fin = false) do (*aplicamos bucle mientras las condicienes de encontrado y fin sea false *)
       
           if biblioteca[i].alta = false then
             begin (*Si alta es false y encontrado es verdadero obtenemos una posición libre*)
             writeln('Encontrada posicion libre');
             encontrado := true;
             posicionlibre := i;
             end
           
           else            
               if i <> TAMBIBLIOTECA then
                 begin  (*sumamos 1 posición a la posición libre*)
                 posicionlibre:= posicionlibre + 1;
                 writeln('Sumamos 1');
                 end
               else
                 begin
                 fin:= true;
                 writeln('Fin');
                 end;
       end;
       
(* begin ##### Innecesario *)
if fin = true then   (* Se nos indica cuando no tenemos más posiciones libres en la biblioteca *)
writeln(' No hay sitio en la tabla para los libros');
if encontrado = true then
begin
lee_libro(biblioteca[posicionlibre]);
writeln('Se ha guardado el libro en la posicion',posicionlibre);
end;
(* end; ##### Innecesario *)
end;


14-May-2011 13:53
Manuel Molina

Nacho,

Gracias por tu contestación. Pero por qué el programa no modifica ni da de baja los datos que se introducen?

saludos


15-May-2011 22:59
Nacho Cabanes (+83)

Para ver por qué no modifica ni da de baja haz lo que he hecho yo:

1) Repasar la lógica del programa. Eso a veces no funciona bien del todo cuando uno revisa su propio programa, porque no se fija realmente en lo que hay escrito sino en lo que "espera que haya escrito", y se escapan los detalles que dan lugar a los fallos.

2) Añadir WriteLn intermedios, que te muestren los valores que van tomando las variables, para poderlos comparar con lo que tú esperas.

¡Duro con ello!






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)