[ Foro de Pascal ]
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.
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;
Nacho,
Gracias por tu contestación. Pero por qué el programa no modifica ni da de baja los datos que se introducen?
saludos
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.)