[ Foro de Pascal ]

Ejemplo básico de agenda con array y record

24-Dec-2011 11:30
Nacho Cabanes (+32)
7 Respuestas

Como es un tema que está tocado con poca profundidad en el curso, he preparado un ejemplo de uso de records y arrays para guardar una especie de "agenda" básica, que enseñe cómo sobredimensionar, cómo guardar datos usando un contador y cómo recorrer los datos existentes para mostrar o buscar.

Si hay interés, puedo crear una versión que use funciones y otra que use ficheros.

Podría ser así:

program Agenda;

type
   tipoPersona = record
       nombre: string;
       email: string;
       anyoNacimiento: integer;
   end;

const
   capacidad = 1000;

var
   gente: array[1..capacidad] of tipoPersona;  { Los datos }
   cantidad: integer;       { Cantidad de datos existentes }
   opcion: integer;                      { Opción escogida }  
   i: integer;                           { Para bucles for }
   textoBuscar: string;                   { Para búsquedas }
   encontrado: boolean;                             { Idem }

{Cuerpo del programa principal}
begin
   cantidad := 0;
   repeat
       WriteLn('Agenda');
       WriteLn;
       WriteLn('1- Añadir una nueva persona');
       WriteLn('2- Ver nombres de todos');
       WriteLn('3- Buscar una persona');
       WriteLn('0- Salir');
       Write('Escoja una opción: ');
       ReadLn(opcion);
       WriteLn;

       case opcion of
           1: { Añadir datos de una persona }
               if (cantidad < capacidad) then
               begin
                   inc(cantidad);
                   WriteLn('Introduciendo la persona ', cantidad);

                   Write('Introduzca el nombre: ');
                   ReadLn(gente[cantidad].nombre);

                   Write('Introduzca el correo electrónico: ');
                   ReadLn(gente[cantidad].email);

                   Write('Introduzca el año de nacimiento: ');
                   ReadLn(gente[cantidad].anyoNacimiento);

                    WriteLn();
                end
                else
                       WriteLn('Base de datos llena');

           2: { Ver nombres de todos }
               begin
               if cantidad = 0 then
                   WriteLn('No hay datos')
               else
                   for i := 1 to cantidad do
                       WriteLn(i, ' ', gente[i].nombre);
               WriteLn;
               end;

           3: { Buscar una persona }
               begin
               Write('¿Qué texto busca? ');
               ReadLn( textoBuscar );
               encontrado := false;
               for i := 1 to cantidad do
                   if pos (textoBuscar, gente[i].nombre) > 0 then
                   begin
                       encontrado := true;
                       WriteLn( i,' - Nombre: ', gente[i].nombre,
                         ', Email: ', gente[i].email,
                         ', Nacido en: ', gente[i].anyoNacimiento);
                   end;
               if not encontrado then
                   WriteLn('No se ha encontrado.');
               WriteLn;
               end;

           0: { Salir de la aplicación }
               begin
               WriteLn;
               WriteLn('Saliendo...');
               WriteLn;
               end;

            else
               begin
               WriteLn;
               WriteLn('Opción incorrecta!');
               WriteLn;
               end;
       end;  { Fin de "case" }

   until opcion = 0;
end.


Lo he publicado también en "errorDeSintaxis.es", porque allí se muestra la sintaxis en colores y lo hará un poco más fácil de leer:

http://www.errordesintaxis.es/verfuente.php?fuente=216


24-Dec-2011 19:43
oscar gomez

Cordial saludo profesor nacho , ante todo una FELIZ NAVIDAD y darte gracias por todo lo que haces por nosotros con tu valiosa ayuda.
me uno a la posibilidad que el mismo ejemplo que desarrollaste ,nos compartieras la solucion en sus versiones utilizando funciones y otra que use ficheros.
y si te es posible nos publiques de igual forma un ejemplo de ejecucion para entenderlo un poco mas en su contexto.mil gracias profesor.


27-Dec-2011 09:37
oscar gomez

Cordial saludo Profesor Nacho cabanes.
Queria saber en el ejemplo que desarrollaste como seria la opcion de eliminacion de un registro en particular de la agenda, por tu orientacion mil gracias


27-Dec-2011 14:30
Nacho Cabanes (+32)

Vamos poco a poco. Primero una versión que use funciones. Algunas variables tendrán que ser globales, o bien pasarse como parámetros. Si somos cuidadosos y lo único que se comparte es el array con los datos, no es un gran problema el que esa variable sea global (realmente, el array y el contador de datos usados).

Podría quedar así:

----

program Agenda;

type
   tipoPersona = record
       nombre: string;
       email: string;
       anyoNacimiento: integer;
   end;

const
   capacidad = 1000;

var
   gente: array[1..capacidad] of tipoPersona;  { Los datos }
   cantidad: integer;       { Cantidad de datos existentes }
   terminado: boolean;

procedure MostrarMenu;
begin
   WriteLn('Agenda');
   WriteLn;
   WriteLn('1- Añadir una nueva persona');
   WriteLn('2- Ver nombres de todos');
   WriteLn('3- Buscar una persona');
   WriteLn('0- Salir');
end;

function LeerOpcion: integer;
var
   opcion: integer;
begin
   Write('Escoja una opción: ');
   ReadLn(opcion);
   WriteLn;
   if (opcion = 0) then terminado := true;
   LeerOpcion := opcion;    
end;

procedure NuevoDato;
begin
   if (cantidad < capacidad) then
   begin
       inc(cantidad);
       WriteLn('Introduciendo la persona ', cantidad);

       Write('Introduzca el nombre: ');
       ReadLn(gente[cantidad].nombre);

       Write('Introduzca el correo electrónico: ');
       ReadLn(gente[cantidad].email);

       Write('Introduzca el año de nacimiento: ');
       ReadLn(gente[cantidad].anyoNacimiento);

        WriteLn();
    end
    else
           WriteLn('Base de datos llena');
end;

procedure MostrarDatos;
var
   i: integer;
begin
   if cantidad = 0 then
       WriteLn('No hay datos')
   else
       for i := 1 to cantidad do
           WriteLn(i, ' ', gente[i].nombre);
   WriteLn;
end;

procedure BuscarDatos;
var
   textoBuscar: string;
   encontrado: boolean;
   i: integer;
begin
   Write('¿Qué texto busca? ');
   ReadLn( textoBuscar );
   encontrado := false;
   for i := 1 to cantidad do
       if pos (textoBuscar, gente[i].nombre) > 0 then
       begin
           encontrado := true;
           WriteLn( i,' - Nombre: ', gente[i].nombre,
             ', Email: ', gente[i].email,
             ', Nacido en: ', gente[i].anyoNacimiento);
       end;
   if not encontrado then
       WriteLn('No se ha encontrado.');
   WriteLn;
end;

{Cuerpo del programa principal}
begin
   terminado := false;
   cantidad := 0;
   repeat

       MostrarMenu;
       case LeerOpcion of
           1: NuevoDato;
           2: MostrarDatos;
           3: BuscarDatos;
           0: { Salir de la aplicación }
               begin
               WriteLn;
               WriteLn('Saliendo...');
               WriteLn;
               end;
            else
               begin
               WriteLn;
               WriteLn('Opción incorrecta!');
               WriteLn;
               end;
       end;  { Fin de "case" }

   until terminado;
end.


27-Dec-2011 15:53
Nacho Cabanes (+32)

A partir de esa versión, se podría crear otra que guardara la información en fichero y la recuperara al empezar la siguiente sesión.

Los cambios podrían ser:

- Se cargan los datos al principio de la sesión, pero sólo si existe el fichero de datos; si el fichero no existe, el programa no debe fallar, sino, en todo caso, avisar.

- Tras cada modificación (por ahora, sólo tras añadir una nueva ficha), se vuelcan todos los datos a fichero, de forma que en caso de pérdida de corriente eléctrica o cualquier otro problema, todo esté guardado.


----


program Agenda;

type
   tipoPersona = record
       nombre: string;
       email: string;
       anyoNacimiento: integer;
   end;

const
   capacidad = 1000;

var
   gente: array[1..capacidad] of tipoPersona;  { Los datos }
   cantidad: integer;       { Cantidad de datos existentes }
   terminado: boolean;

procedure MostrarMenu;
begin
   WriteLn('Agenda');
   WriteLn;
   WriteLn('1- Añadir una nueva persona');
   WriteLn('2- Ver nombres de todos');
   WriteLn('3- Buscar una persona');
   WriteLn('0- Salir');
end;

function LeerOpcion: integer;
var
   opcion: integer;
begin
   Write('Escoja una opción: ');
   ReadLn(opcion);
   WriteLn;
   if (opcion = 0) then terminado := true;
   LeerOpcion := opcion;    
end;


procedure CargarDatos;
var
   fichero: file of tipoPersona;
   i: integer;
begin
   assign(fichero, 'agenda.dat');
   {$I-}
   reset(fichero);
   {$I+}
   if ioResult <> 0 then  
       WriteLn('No había fichero de datos. Se creará.')
   else
   begin
       cantidad := filesize(fichero);
       for i := 1 to cantidad do
           Read(fichero, gente[i]);
       close(fichero);
   end;
end;

procedure GrabarDatos;
var
   fichero: file of tipoPersona;
   i: integer;
begin
   assign(fichero, 'agenda.dat');
   {$I-}
   rewrite(fichero);
   {$I+}
   if ioResult <> 0 then  
       WriteLn('No se ha podido grabar!')
   else
   begin
       for i := 1 to cantidad do
           Write(fichero, gente[i]);
       close(fichero);
   end;
end;

procedure NuevoDato;
begin
   if (cantidad < capacidad) then
   begin
       inc(cantidad);
       WriteLn('Introduciendo la persona ', cantidad);

       Write('Introduzca el nombre: ');
       ReadLn(gente[cantidad].nombre);

       Write('Introduzca el correo electrónico: ');
       ReadLn(gente[cantidad].email);

       Write('Introduzca el año de nacimiento: ');
       ReadLn(gente[cantidad].anyoNacimiento);

        WriteLn();
        GrabarDatos;
    end
    else
           WriteLn('Base de datos llena');
end;

procedure MostrarDatos;
var
   i: integer;
begin
   if cantidad = 0 then
       WriteLn('No hay datos')
   else
       for i := 1 to cantidad do
           WriteLn(i, ' ', gente[i].nombre);
   WriteLn;
end;

procedure BuscarDatos;
var
   textoBuscar: string;
   encontrado: boolean;
   i: integer;
begin
   Write('¿Qué texto busca? ');
   ReadLn( textoBuscar );
   encontrado := false;
   for i := 1 to cantidad do
       if pos (textoBuscar, gente[i].nombre) > 0 then
       begin
           encontrado := true;
           WriteLn( i,' - Nombre: ', gente[i].nombre,
             ', Email: ', gente[i].email,
             ', Nacido en: ', gente[i].anyoNacimiento);
       end;
   if not encontrado then
       WriteLn('No se ha encontrado.');
   WriteLn;
end;


{Cuerpo del programa principal}
begin
   terminado := false;
   cantidad := 0;
   CargarDatos;
   repeat

       MostrarMenu;
       case LeerOpcion of
           1: NuevoDato;
           2: MostrarDatos;
           3: BuscarDatos;
           0: { Salir de la aplicación }
               begin
               WriteLn;
               WriteLn('Saliendo...');
               WriteLn;
               end;
            else
               begin
               WriteLn;
               WriteLn('Opción incorrecta!');
               WriteLn;
               end;
       end;  { Fin de "case" }

   until terminado;
end.


29-Dec-2011 14:56
Nacho Cabanes (+32)

Atendiendo a la petición de Óscar, en primer lugar incluyo un ejemplo de ejecución de la última versión. Se puede ver que la primera vez, que no hay fichero de datos, se crea uno vacío. la segunda vez que se lanza el programa, como ya existe fichero de datos, se puede empezar consultando los datos anteriores.

------------------------------

No había fichero de datos. Se creará.
Agenda

1- Añadir una nueva persona
2- Ver nombres de todos
3- Buscar una persona
0- Salir
Escoja una opción: 1

Introduciendo la persona 1
Introduzca el nombre: Juan
Introduzca el correo electrónico: 1@1.1
Introduzca el año de nacimiento: 1

Agenda

1- Añadir una nueva persona
2- Ver nombres de todos
3- Buscar una persona
0- Salir
Escoja una opción: 2

1 Juan

Agenda

1- Añadir una nueva persona
2- Ver nombres de todos
3- Buscar una persona
0- Salir
Escoja una opción: 0


Saliendo...

------------------------------

Agenda

1- Añadir una nueva persona
2- Ver nombres de todos
3- Buscar una persona
0- Salir
Escoja una opción: 2

1 Juan

Agenda

1- Añadir una nueva persona
2- Ver nombres de todos
3- Buscar una persona
0- Salir
Escoja una opción: 3

¿Qué texto busca? a
1 - Nombre: Juan, Email: 1@1.1, Nacido en: 1

Agenda

1- Añadir una nueva persona
2- Ver nombres de todos
3- Buscar una persona
0- Salir
Escoja una opción: 0


Saliendo...

------------------------------

Mejoras posibles (como ejemplo):

- Borrar datos (se borra del array, desplazando los siguientes "hacia la izquierda", y se guardan los cambios)

- Ordenar datos (burbuja por ejemplo, guardando cambios después)

- Modificar datos (lo ideal es que se amigable: se muestra el valor anterior, se modifica si se teclea algo y no se modifica si se pulsa intro; se guardan cambios después)

- Pantalla con colores


Se aceptan propuestas de solución para estas mejoras, o nuevas sugerencias.


29-Dec-2011 17:36
oscar gomez

Cordial saludo profesor Nacho Cabanes,gracias por atender mi peticion.
Profesor queria preguntarte es que no comprendo muy bien esta parte de tu codigo:
Escoja una opción: 3

¿Qué texto busca? a
1 - Nombre: Juan, Email: 1@1.1, Nacido en: 1

es decir que pasa o que se pide cuando se escoje la opcion 3,mil gracias por tu ayuda y explicacion.


29-Dec-2011 20:31
Nacho Cabanes (+32)

Mira el menú:

-------------
Agenda

1- Añadir una nueva persona
2- Ver nombres de todos
3- Buscar una persona
0- Salir

-------------

Es decir, la opción 3 es la de buscar. Introduces un texto y te muestra las personas que lo contienen en el nombre. La parte básica encargada de conseguirlo sería esta:

for i := 1 to cantidad do
  if pos (textoBuscar, gente[i].nombre) > 0 then
      WriteLn( i, ' ', gente[i].nombre);

pero si miras el fuente completo, verás que es un poco más detallado, porque da un mensaje de aviso si no lo encuentra, y muestra todos los datos (no solo el nombre) en caso de encontrarlo.






(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.)