Un ejemplo del uso de Punteros: manejo de cantantes Un

Anuncio
Elementos de Programación / 2000 / Prof. Carlos Iván Chesñevar
1
Un ejemplo del uso de Punteros: manejo de cantantes
Un diskjockey desea contar con un programa que permita manejar información sobre
cantantes. Desea manejar información sobre varios cantantes. A cada cantante le asigna un
número que lo identifica (ej: entre 1 y 1000). Algunos cantantes –en opinión del diskjockeytienen identificado un mejor tema, y en tal caso el diskjockey desea guardar la cadena
correspondiente al nombre de dicho tema.
Escribir un programa que permita manejar la información que desea el diskjockey. La
información se deberá cargar en una tabla. El programa deberá también permitir transferir la
tabla a un archivo y viceversa.
Ejercicios adicionales:
a)
Modifique el programa anterior para permitir eliminar cantantes de la tabla. Cuidado: puede ser
necesiario utilizar dos veces la sentencia dispose, aunque no siempre, para eliminar a un cantante de la
tabla (por qué?).
b) Escriba un procedimiento GenerarArchivoTemas que genere un archivo de texto Temas.txt. Dicho
archivo de texto contendrá el nombre de todos los cantantes que tienen un mejor tema conocido. Su
archivo deberá tener una apariencia como la siguiente:
NOMBRE
Marcela Morelo
Noelia
Britney Spears
Shakira
Cheyenne
…
TEMA
Ponernos de acuerdo
Candela
I did it again
Ojos así
(No se conoce tema)
....
c) Escriba otro procedimiento MostrarArchivoTemas que permita mostrar el archivo anterior por pantalla.
Program P;
{ Programa para manejo de datos de cantantes }
Const
TopeTabla = 1000;
Type
TOpcion
= 1..5;
TCadena
= string;
TMejorTema = TCadena;
{opciones disponibles}
{cadena de caracteres de longitud arbitraria}
{los temas son cadenas}
TCantante
= Record
{por cada cantante, guardamos nombre y mejor tema}
Nombre: TCadena;
MejorTema: ^TMejorTema;
End;
TPunCantante = ^TCantante;
TIndiceTabla = 1..TopeTabla;
{ Datos de un cantante para almacenar en un archivo }
TDatosDeCantante = Record
NroCantante : TIndiceTabla;
Nombre,MejorTema:TCadena;
End;
Elementos de Programación / 2000 / Prof. Carlos Iván Chesñevar
{ Tabla de cantantes }
TTablaCantantes = Record
Datos: Array [1..TopeTabla] of TPunCantante;
UltimoCantanteIngresado:0..TopeTabla;
End;
{ Archivo de cantantes }
TArchivoCantantes = File of TDatosDeCantante;
Var
T: TTablaCantantes;
A: TArchivoCantantes;
Opcion:TOpcion;
{..............................................}
Procedure InicializarTabla(Var T:TTablaCantantes);
{ Dada una tabla T, inicializa el contenido con valor nil,
para todos los cantantes posibles.}
Var i:TIndiceTabla;
Begin
T.UltimoCantanteIngresado:=0;
For i:=1 to TopeTabla
do
T.Datos[i]:=nil;
End;
{..............................................}
Procedure CargarCantante(Var C:TCantante);
{ Dado un registro C:TCantante, permite al usuario cargar
sus campos. Notese que el mejor tema es un puntero
a una cadena, y el valor de dicho puntero es nil en
caso de que no haya un mejor tema asociado a C}
Var Tema:TCadena;
Begin
write('Nombre:');
readln(C.Nombre);
write('Mejor tema? (0=no tengo preferencia): ');
readln(Tema);
If Tema<>'0'
then
begin
new(C.MejorTema);
C.MejorTema^:=Tema;
end
else
C.MejorTema := nil;
End;
{............................................}
Procedure InsertarCantante(Var T:TTablaCantantes);
{ Permite agregar un nuevo cantante en la tabla T;
el cantante se aniade siempre al final de la tabla }
Var i:TIndiceTabla;
Begin
If T.UltimoCantanteIngresado < TopeTabla
then
Begin
T.UltimoCantanteIngresado := T.UltimoCantanteIngresado+1;
i := T.UltimoCantanteIngresado;
writeln('Ingrese los datos de un cantante:');
2
Elementos de Programación / 2000 / Prof. Carlos Iván Chesñevar
new(T.Datos[i]);
CargarCantante(T.Datos[i]^);
End
else
writeln('Tabla llena!');
End;
{............................................}
Procedure MostrarMejoresTemas(Var T:TTablaCantantes);
{ recorre toda la tabla T, y muestra los nombres de los
cantantes en la tabla, y sus mejores temas, si existen }
Var i:TIndiceTabla;
Begin
For i:=1to T.UltimoCantanteIngresado
do
Begin
If T.Datos[i]<>nil
then
With T.Datos[i]^
do
begin
writeln('**************************************');
writeln('Cantante ',i);
write('Nombre:'); writeln(Nombre);
write('Mejor tema:');
If T.Datos[i]^.MejorTema = nil
then
writeln('No se conoce mejor tema')
else
writeln(T.Datos[i]^.MejorTema^);
end;
End;
End;
{........................................................}
Procedure Pasar_tabla_a_archivo(Var T:TTablaCantantes;
Var A:TArchivoCantantes);
{ Este procedimiento transfiere todos los datos de T a un
archivo A. Notese que se realiza una "transformacion" que
copia el contenido de las componentes de T en registros
de tipo TDatosDeCantante, los cuales se guardan en A}
Var DatosDeCantante:TDatosDeCantante;
i : TIndiceTabla;
Begin
rewrite(A);
For i:=1 to T.UltimoCantanteIngresado
do
Begin
If T.Datos[i]<>nil
then
begin
DatosDeCantante.NroCantante:=i;
DatosDeCantante.Nombre := T.Datos[i]^.Nombre;
If T.Datos[i]^.MejorTema<>nil
then
DatosDeCantante.MejorTema := T.Datos[i]^.MejorTema^
else
DatosDeCantante.MejorTema :='@';
write(A,DatosDeCantante);
end;
3
Elementos de Programación / 2000 / Prof. Carlos Iván Chesñevar
End;
close(A);
End;
{............................................................}
Procedure Pasar_archivo_a_tabla(Var T:TTablaCantantes;
Var A:TArchivoCantantes);
{ Este procedimiento transfiere el contenido del archivo A
a la tabla T. Notese que el valor de T.UltimoCantanteIngresado
sera el valor mas grande de entre los nros. de cantantes que
aparezcan en A}
Var DatosDeCantante:TDatosDeCantante;
MaximoNroCantante:0..TopeTabla;
i : TIndiceTabla;
Begin
reset(A);
InicializarTabla(T);
MaximoNroCantante:=0;
while not eof(A)
do
begin
read(A,DatosDeCantante);
If DatosDeCantante.NroCantante > MaximoNroCantante
then
MaximoNroCantante := DatosDeCantante.NroCantante;
i := DatosDeCantante.NroCantante;
{ i = nro. del cantante}
new( T.Datos[i] ); {se crea un registro en pos. i-esima de T}
With T.Datos[i]^
do
begin
Nombre := DatosDeCantante.Nombre; {se guarda el nombre}
If DatosDeCantante.MejorTema <>'@' { y si existe un mejor tema}
then
begin
{se crea un puntero a una cadena}
new(T.Datos[i]^.MejorTema);
{ y en dicha cadena se almacena el nombre del mejor tema}
T.Datos[i]^.MejorTema^:=DatosDeCantante.MejorTema;
end
else
T.Datos[i]^.MejorTema:=nil
end;
end;
T.UltimoCantanteIngresado := MaximoNroCantante;
End;
{............................................}
Procedure Menu(Var Opcion:TOpcion);
{ Este procedimiento simplemente permite al usuario elegir
de entre varias opciones disponibles, mostrando los carteles
apropiados }
Begin
writeln('--------------------------------------- ');
writeln('
Manejo de Cantantes
');
writeln('--------------------------------------- ');
writeln;
writeln('1) Insertar nuevo cantante');
writeln('2) Mostrar mejores temas');
writeln('3) Pasar tabla a un archivo');
4
Elementos de Programación / 2000 / Prof. Carlos Iván Chesñevar
writeln('4) Pasar archivo a una tabla');
writeln('5) Salir');
write('Su opcion:');
readln(Opcion);
End;
{ ..........................................................}
Begin {ppal}
assign(A,'c:\canta.dat');
Repeat
Menu(Opcion);
Case Opcion of
1 : InsertarCantante(T);
2 : MostrarMejoresTemas(T);
3 : begin
writeln('Su tabla sera almacenada en un archivo');
writeln('y se destruira el contenido preexistente de');
writeln('dicho archivo...');
Pasar_tabla_a_archivo(T,A);
end;
4 : begin
writeln('Su tabla actual sera cargada con informacion');
writeln('de un archivo.. los datos actuales de la tabla');
writeln('se borraran');
Pasar_archivo_a_tabla(T,A);
end;
end;
Until Opcion=5; {salir}
End.
5
Descargar