UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. 22. ARCHIVOS. Files 22.1. Conceptos de Archivos. Una forma de estructurar datos es la secuencia; consistente en una secuencia de un número arbitrario de componentes de un mismo tipo, que se denomina base. La secuencia está definida con cardinalidad no acotada; es decir, no puede saberse, por adelantado, el número de componentes de la secuencia. El número de elementos se denomina largo; una secuencia de largo cero se denomina vacía. Una secuencia es un modelo abstracto que permite representar la información depositada en una cinta magnética, en un disco, en un tambor, cinta de papel; también pueden representarse por secuencias las informaciones que fluyen hacia una impresora, o desde un teclado, o la que viaja hacia una pantalla. También pueden tenerse secuencias en la memoria principal; cadenas o strings, listas, pilas (stacks), colas (queues) y dobles colas (dequeues). Como el número de valores de una secuencia no se conoce por adelantado, la cantidad de almacenamiento necesaria para guardar un valor de la secuencia no puede determinarse en el momento de la compilación. Queda determinado cuando el programa que la emplea está en ejecución; y en muchos casos el largo de la secuencia varía durante la ejecución del programa. Por esto se dice que una secuencia es una estructura dinámica. Cuando el tamaño de una estructura es elevado, es más eficiente disponer de instrucciones que permitan la actualización individual de una componente, en lugar de refrescar toda la estructura. Se denomina archivo secuencial, o más simplemente archivo, a la representación de una secuencia en memoria secundaria (generalmente discos). La manipulación de los discos es realizada por el sistema operativo, en cuyo diseño se han contemplado las características físicas de los dispositivos: número de pistas y sectores, número de superficies, tiempo de movimiento de las cabezas y período de rotación del medio. Como el tiempo de acceso es lento, no suele leerse o escribirse un byte, sino que un bloque. El que también es una secuencia, y puede tener un tamaño múltiplo de 128; usualmente 512 bytes. El sistema operativo reserva un espacio de memoria principal para almacenar el bloque que ha sido leído, o será, escrito en el disco. Este espacio suele llamarse el buffer del disco. No existe una traducción única para este concepto, una posibilidad es almacén; otra es Prof. Leopoldo Silva Bijit. 07-07-2003 271 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. amortiguador, en el sentido de parachoques, es algo que está en medio. Cuanto mayor sea el tamaño del buffer menor será el número de accesos al disco, lo cual tiende a mantener el proceso en el rango de velocidad de las componentes electrónicas y no en el de las electromecánicas. Las implementaciones de Pascal, mantienen en memoria principal un espacio para almacenar sólo un valor del tipo base. Nos referiremos a este espacio como el buffer del archivo. Como el uso es estrictamente secuencial, cuando se desea obtener un nuevo valor, se accesa al buffer del disco; cuando éste ha sido consumido, el sistema operativo lo vuelve a llenar y así hasta consumir todo el archivo. El proceso recién descrito queda oculto (o abstraído) en la representación de archivos que veremos a continuación. 22.2. Sintaxis. En la declaración: Type F = file of B; var x : F; F es el nombre del tipo archivo, formado por una secuencia de valores de tipo base B. La variable x, de tipo F, se denomina nombre lógico del archivo. La declaración de x, crea un espacio (para guardar un valor de tipo base), que se denomina buffer del archivo, y que se anota: x^ A esta variable, también se la denomina ventana del archivo. El nombre recuerda que la representación de un archivo, mantiene solamente una componente del archivo en forma visible (o accesible), en cada instante. Asociada a esta variable, existe una posición en la secuencia del archivo, en memoria secundaria. Esta posición corriente tiene un valor que también se mantiene en la variable ventana, en memoria principal. La asociación del buffer con la posición en el archivo se recuerda en la flecha del símbolo. 22.3. Manipulación. Prof. Leopoldo Silva Bijit. 07-07-2003 272 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. Gráficamente, el espacio involucrado, puede verse: 1 2 3 4 ………. n En el disco X posición corriente x^ * En memoria modo: eof(x): largo: lectura false n Puede visualizarse, que la secuencia superior se desplaza, siempre queda la ventana asociada a la posición corriente. Asociado al archivo x, existe la función estándar eof(x), que toma el valor true sólo cuando la posición corriente intenta apuntar después de la última componente. Un archivo puede estar en modo lectura o escritura, pero no en ambos. En Pascal estándar se controla el modo con las instrucciones reset(x) y rewrite(x). La primera abre el archivo en modo lectura, es equivalente al rewind empleado en toca cassettes. Rewrite abre un archivo para escritura, más específicamente para reescritura; en un toca cassettes equivale a un rebobinado más la opresión de la tecla grabación. El largo no es accesible, se ha incluido como una coordenada característica de un archivo. Si el largo es cero, se dice que el archivo es vacío. Para describir las 4 operaciones básicas o primitivas de manipulación emplearemos las 5 características básicas de un archivo: la posición corriente, el valor de la ventana, la condición eof, el modo y el largo. a) Rewrite(x). Reescritura. Permite construir una secuencia vacía. Si existía información asociada a x, se borra. Queda eof(x) con valor verdadero. El modo queda en escritura. Prof. Leopoldo Silva Bijit. 07-07-2003 273 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. El largo toma el valor cero. El valor de la ventana queda indefinido. La posición corriente queda a la extrema izquierda, no marca ninguna componente. b) Put(x). Pone. Previa a la ejecución de put(x), debe asignarse un valor a la variable ventana. Además sólo puede escribirse si eof(x) es verdadero. Conceptualmente, la única forma de agregar una componente a una secuencia, es hacerlo al final de ella. Su ejecución agrega, el valor de la ventana, en una nueva componente al final del archivo. El largo se incrementa en 1. La posición corriente queda apuntando a una componente inexistente a la extrema derecha. eof(x) se mantiene verdadero. La variable ventana queda indefinida. Permanece en modo escritura. Este modo se logra si eof(x) es verdadero. c) Reset(x). Preparación para leer. Se emplea cuando se desea leer un archivo ya existente. Si el archivo no es vacío; o sea si largo>0. Queda eof(x) con valor false. x^ queda con una copia del valor de la primera componente. Se entra al modo lectura, ya que eof(x) es false. Si el archivo es vacío, la ventana queda indefinida y eof(x) permanece true. Si se tiene un archivo y se desea escribir en él, se lo debe abrir con un reset; y luego avanzar hasta llegar a tener eof(x) verdadero; momento en el cual queda en modo escritura. Prof. Leopoldo Silva Bijit. 07-07-2003 274 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. d) Get(x). Traiga. La posición corriente avanza una posición. El valor de la componente apuntada se copia en la variable ventana. Sólo puede efectuarse esta instrucción si eof(x) es false. Si no hay una próxima componente, al avanzar la posición corriente fuera del archivo, se coloca eof(x) en valor verdadero; y la ventana queda indefinida. 22.4. Aplicaciones de los primitivos de manipulación de archivos. a) Copia de archivos de texto, líneas de entrada se truncan a largo 80. program copia(in,out); var in,out:text; i : integer; linea: array[1..80] of char; {se emplea un buffer de línea en memoria principal} procedure lealinea; begin i:=0; while (not eof(in)) and i<80 do begin i:=i+1;read(in, linea[i]) end; readln(in) end; procedure escribalinea; var j: integer; begin for j:=1 to i do write(out,linea[j]); writeln(out) end; begin {copy} reset(in); {open(in,'<nombre>',input)} Prof. Leopoldo Silva Bijit. 07-07-2003 275 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. rewrite(out); {open(out,'<nombre>',output)} while not eof(in) do begin lealinea; {aquipuedehaberprocesamiento adicional} escribalinea(out,linea) end end. b) Copia de archivos en general. (Pueden no ser de texto) program copia(in,out); var in, out: file of tipo; {tipo entero copia} begin {casi todo.} reset(in); rewrite(out); while not eof(in) do begin out^:=in^; get(in); put(out) end end. c) Esquema de construcción secuencial. ... rewrite(x); while condicion do begin generación de valor de v; x^:=v; put(x) end; ... d) Esquema de inspección o procesamiento secuencial. ... reset(x); while not eof(x) do begin v:=x^; Prof. Leopoldo Silva Bijit. 07-07-2003 276 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. get(x); {prepara el siguiente} proceso con variable v end; ... e) Generación de respaldo. Copia fiel. program respaldo(datos,respaldo); var datos, respaldo:file of items; begin rewrite(respaldo); reset(datos); while not eof(datos) do begin respaldo^:=datos^; put(respaldo); get(datos) end end. 22.5. Lectura y Escritura en archivos. En base a las primitivas se elaboran las instrucciones básicas de entrada salida, read y write, que se han estado empleando. a) Lectura. La instrucción read(f,x) es equivalente a la secuencia: x := f^; get(f) Es decir, copia la ventana en la variable x, y avanza a la siguiente posición. Esta implementación es válida si se trata de un archivo externo. En el caso de archivos interactivos, el estándar de entrada, por su naturaleza no puede disponerse del valor de la ventana, ya que aún no se ha leído. En archivos interactivos, la instrucción read(f,x) se implementa según: get(f); x:=f^ b) Escritura. Prof. Leopoldo Silva Bijit. 07-07-2003 277 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. La instrucción write(f,x) es equivalente a la secuencia: f^:=x; put(f) Es decir, llena la ventana con el valor de la expresión x y la coloca en la última posición. Las equivalencias anteriores son válidas para cualquier tipo de archivo. Debe observarse que la lectura según tipos y la escritura formateada de expresiones, son válidas solamente para archivos de texto. Entendemos por lectura de acuerdo al tipo, cuando se efectúa un análisis según la estructura léxica del tipo; en este caso, cuando se leen enteros se descartan espacios. 22.6. Clases de Archivos. a) Externos. Los archivos pueden ser externos; es decir, existen fuera del programa principal. Deben ser declarados como variables globales, y los nombres de las variables, de dichos archivos, deben figurar en la lista de parámetros del programa. b) Internos. En Pascal estándar, también es posible trabajar con archivos locales. Para ello sólo basta definirlos como variables locales dentro de procedimientos. Existen mientras esté activo el procedimiento. Otra posibilidad es definir un archivo local con el programa; en este caso son declarados globales; pero no figuran en la lista de parámetros del programa. El empleo de archivos internos debe ser una necesidad dependiente de las características de los datos y el tipo de procesamiento. Lo esencial es la generación o procesamiento de una secuencia, cuya cardinalidad no se conoce de antemano. 22.7. Archivos de Registros. 22.7.1. Introducción a procesamiento de Datos. Prof. Leopoldo Silva Bijit. 07-07-2003 278 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. Esta estructura de datos es, sin lugar a dudas, la más empleada en procesamiento de datos; es decir, todas aquellas situaciones en que se manipulan grandes volúmenes de información, con operaciones simples, en general. La información básica tradicionalmente manejados por los sistemas de información administrativa (SIA): contabilidad, facturación, cuentas corrientes, liquidación de sueldos, inventario; pueden describirse mediante archivos de registros, o más simplemente archivos, como se los denomina en la práctica. Existen lenguajes de programación, como COBOL, desarrollados especialmente para este tipo de datos. En la actualidad existen programas denominados: administradores de bases de datos relacionales, que también son muy poderosos en la manipulación de archivos de registros. Por otro lado, la computación científica se caracteriza, en general, por una gran manipulación de pequeños volúmenes de datos. Pascal, es uno de los primeros lenguajes dotados con una capacidad para estructurar datos. Es decir, para crear nuevos espacios de datos (tipos). Lo cual le permite adaptarse a casi todas las situaciones de programación. En lo que sigue, se explora en un ambiente de procesamiento de archivos de registros en Pascal; lo cual presentará los conceptos básicos en este ambiente, los que posteriormente podrán ser desarrollados en otros lenguajes más adecuados a este fin. Además el análisis de este problema, ilustra la técnica para crear nuevas estructuras de datos, acompañadas de procedimientos especiales que las manipulen. 22.7.2.-Diseño del registro. Generalmente uno de los campos, permite identificar unívocamente a un registro. Este campo se llama clave o entidad; el resto de los campos son los atributos o cualidades de la entidad. En general: type registro=record clave:tipoclave; atrib1:tipo1; | atribn:tipon end; Prof. Leopoldo Silva Bijit. 07-07-2003 279 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. En particular, los nombres de los campos y los tipos dependerán del problema específico. Deben definirse procedimientos especiales para manipular el registro. Entre ellos podemos mencionar: a) Test de igualdad. Consiste en desarrollar una función, de tipo booleano, que indique si la clave del registro, de la ventana o buffer, es igual o no a algún valor dado. b) Llenar un registro desde el teclado. Si los tipos de los campos, no son manipulados por la instrucción read, deberán desarrollarse procedimientos para leer los campos. Este será el caso, por ejemplo, si un campo es a su vez otro registro, o un arreglo. Este procedimiento puede permitir repetir el ingreso de un registro, hasta que se de una aprobación explícita. Esto permite efectuar correcciones, debidas a malas digitaciones u otros errores. Si se conoce que algún campo cumple alguna propiedad, el procedimiento puede efectuar una validación. Por ejemplo si es una fecha, puede asegurarse que ésta sea correcta. A veces la información se codifica numéricamente; por ejemplo se emplea números múltiplos de once para describir los diferentes valores (no obligatoriamente numéricos) de un campo; esto asegura que puede detectarse un número mal digitado. Lo anterior es debido a que dos números del código difieren, por lo menos en dos dígitos; por supuesto que si se digitan mal dos números, no habrá detección del error. En otros casos, como en el rol único tributario (R.U.T) se agrega un dígito verificador. El que se construye en base al resto de los números. Verificación. En general, en los sistemas pequeños se emplea la validación óptica, consistente en releer en la pantalla los valores digitados, y efectuar correcciones, si es necesrio. Sumas de control. Otra técnica, cuando existen números, es por ejemplo, digitar los números y la suma de éstos. El computador revisa que la suma generada localmente sea igual a la suministrada y Prof. Leopoldo Silva Bijit. 07-07-2003 280 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. también digitada. Este procedimiento con sumas de control, suele generalmente emplearse con un grupo de registros. Si el campo, o campos, controlados no cumplen la suma de control, deberán eliminarse del archivo, y volver a ingresarse. Validación. En grandes sistemas, suelen digitarse los datos dos veces; y luego el computador, en el segundo ingreso, va detectando errores. También en sistemas grandes, suelen ingresarse los datos y luego se valida un campo revisando si los valores de éstos, están presentes en otro archivo que contiene el dominio del campo. A esto se le llama validación batch (o por tandas). En este ambiente los datos vienen en comprobantes (o vouchers, en francés) diseñados especialmente para el registro. En el desarrollo de la lectura de un registro, pueden ser muy útiles procedimientos para manejar el cursor y los atributos de video: Borrar la pantalla, posicionar el cursor en determinadas coordenadas, borrar línea, borrar desde donde está el cursor hasta el final de la línea o de la pantalla. Escribir, cierta zona, en video inverso; o bien en forma parpadeante (blinking) o subrayado, o en mediana intensidad. También, casi todos los terminales modernos, permiten escribir caracteres especiales (llamados gráficos) que posibilitan dibujar recuadros. b) Escribir un registro en la pantalla. Este procedimiento es mucho más simple; y ayudado por los subprogramas para manipular la pantalla, son muy sencillos de implementar. Sólo habría que destacar, que si un campo tiene un tipo no manipulado por la instrucción write, deberá escribirse un procedimiento especial, para ese campo. c) Escribir un registro en un archivo de texto. Esto suele emplearse para generar reportes mediante impresoras. La impresoras modernas, generalmente aceptan secuencias de caracteres que activan rasgos especiales de impresión. Enfatizado, comprimido, doble ancho, cambio de interlínea, posiciones de tabulación horizontal y vertical, cambio de hoja, etc.. Prof. Leopoldo Silva Bijit. 07-07-2003 281 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. En estos casos suelen escribirse algunos campos en determinadas posiciones, empleando caracteres para separarlos, y mantener columnas alineadas. También pueden escribirse columnas, que se generen calculando expresiones con los campos del registro. Cada cierto número de líneas, pueden escribirse totales y subtotales; también puede escribirse el número de página y un encabezado que especifica el contenido de las columnas. d) Leer y escribir un registro en un archivo. Si el archivo de registros, no es de texto, deben emplearse procedimientos especiales para leer un registro desde la ventana, y para llevar la ventana y colocarla en un archivo. e) Manipulación de un buffer. Todos los procedimientos anteriores, contemplan una variable visible de tipo registro; generalmente diferente de la ventana del archivo. Este espacio puede ser inadecuado, debido a la característica secuencial de los archivos en Pascal, de no poder retroceder. Una alternativa útil es definir un arreglo de registros o buffer. Esto permite leer varios registros, revisarlos en conjunto; y luego escribirlos en el disco. También puede llenarse el arreglo, con una parte del archivo, y efectuar procesos en el arreglo; consumido éste, puede volver a llenarse con nuevos registros traídos desde el archivo, y así hasta agotarlo. En este caso debe ponerse especial cuidado al tratamiento del final del archivo, ya que generalmente el número de registros del archivo, no es un múltiplo de la dimensión del arreglo. 22.7.3. Operaciones sobre el archivo. Las operaciones básicas son: -Agregar, al final, un nuevo registro. -Borrar un determinado registro. -Modificar cierto registro. -Listar, en grupos, el contenido del archivo. Las acciones de borrar y modificar, requieren un procedimiento de búsqueda. El cual consiste básicamente de un procesamiento secuencial y la aplicación de la función que verifica la igualdad de un valor dado con el campo determinado. Operaciones más complejas son: Prof. Leopoldo Silva Bijit. 07-07-2003 282 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. -Buscar todos los registros que cumplan con cierta condición, y generar un listado o un nuevo archivo. Esta acción también se denomina extraer. Más compleja será la búsqueda, mientras más complicada sea la condición. -Ordenar el archivo, de acuerdo a los valores de un campo, generalmente la clave. (Sorting). -Juntar dos archivos, previamente ordenados por un campo, generando un archivo único ordenado. Esto suele llamarse mezcla (o merging en inglés). -Unir (join) consiste en trabajar con dos archivos y generar uno nuevo, que contenga algunos campos de un archivo, que cumplan una condición; con todos o algunos de los campos de un registro del otro archivo, que cumplan cierta condición. -Actualización. Esta es una de las operaciones más corrientes, en las que intervienen dos archivos. Uno denominado maestro y otro llamado de transacciones. En el caso más general, uno de los campos de transacciones indica la acción a realizar: borrar un registro en el maestro, agregar uno nuevo, sumar valores de transacciones en determinados campos y registro del maestro, etc.. Si bien es posible desarrollar todas estas acciones en Pascal, existen lenguajes mucho más adecuados para estas labores. En nuestro país la mayoría de estas aplicaciones se programan en Cobol, y recientemente se están empleando bases de datos para las mismas labores. 22.7.4. Ejemplo. Archivo de Registros. Se tiene el siguiente Menú para la manipulación de un archivo INFO.DAT de registros : MENU 1. CARGAR ARCHIVO INFO.DAT CON DATOS. 2. VER CONTENIDO DE ARCHIVO INFO.DAT (LISTAR). 3. AGREGAR INFORMACION A INFO.DAT. 4. MODIFICAR ROL DEL ALUMNO. 5. BORRAR UN ALUMNO DEL ARCHIVO. 6. VER SI UN ALUMNO ESTA EN EL ARCHIVO. DIGITE OPCION ---> Y se tiene el siguiente segmento de programa : READ(OPCION); {OPCION ES DE TIPO ENTERO} CASE OPCION OF 1: CARGAR; 2: LISTAR; Prof. Leopoldo Silva Bijit. 07-07-2003 283 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. 3: AGREGAR; 4: MODIFICAR_ROL; 5: BORRAR; 6: MIEMBRO END; Desarrollar cada uno de los procedimientos de acuerdo a lo indicado en Menú. Con la siguiente estructura para el registro, que es el componente base del archivo INFO.DAT: TYPE ALUMNO = RECORD rol : INTEGER; nombre : PACKED ARRAY[1..32] OF CHAR; subcampo : RECORD asignatura:PACKEDARRAY[1..20]OF CHAR; nota : REAL END END; ARCHIVO = FILE OF ALUMNO; VAR ENT : ARCHIVO; Solución. Para compactar el código se declara un procedimiento global. PROCEDURE LEER; {lee desde pantalla el valor de cada campo de los registros que se desean escribir en el archivo INFO.DAT} VAR I : INTEGER; CH : CHAR; BEGIN REPEAT WRITELN; WRITE('ROL: '); READLN(ENT^.rol); {asigna valor leído a ROL} FOR I:=1 TO 32 DO Prof. Leopoldo Silva Bijit. 07-07-2003 284 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. ENT^.nombre[I]:=' '; {limpia cambio nombre} WRITE('NOMBRE: '); I:=0; REPEAT I:=I+1; READ(ENT^.nombre[I]) {lee caracter a caracter} UNTIL (ENT^.nombre[I]='.') OR (I=32); READLN; WRITE('ASIGNATURA'); FOR I:=1 TO 20 DO READ(ENT^.subcampo.asignatura[I]); READLN; WRITE('NOTA: '); READLN(ENT^.subcampo.nota); PUT(ENT); {actualiza} WRITE('SEGUIMOS (S/N)? : '); READ(CH); UNTIL CH='N' END; (1) PROCEDURE CARGAR; {El procedimiento CARGAR escribe los datos en el archivo, limpiando inicialmente todo el archivo} BEGIN OPEN(ENT,INFO.DAT,OUTPUT); REWRITE(ENT); {limpia archivo} LEER; CLOSE(ENT) END; (2) PROCEDURE LISTAR; {LISTAR imprime en pantalla un registro por línea, y 20 a la vez, del archivo INFO.DAT} VAR I,J : INTEGER; CH : CHAR; BEGIN OPEN(ENT,INFO.DAT,INPUT); RESET(ENT); {prepara archivo para su lectura} Prof. Leopoldo Silva Bijit. 07-07-2003 285 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 22. Archivos. Files. REPEAT WRITELN; I:=0; {inicializa número de registros a imprimir} WRITELN('ROL NOMBRE ASIGNATURA NOTA '); WHILE (NOT EOF(ENT)) AND (J<20) DO BEGIN WRITE(ENT^.ROL:5); WRITE(' ':3); FOR I:=1 TO 32 DO WRITE(ENT^.nombre[I]); WRITE(' ':3); FOR I:=1 TO 20 DO WRITE(ENT^.subcampo.asignatura[I]); WRITELN(ENT^.subcampo.nota:7:2); {hasta aquí se ha imprimido 1 reg. en la línea} GET(ENT); {avanza al sgte. componente} J:=J+1; {incrementa contador de registros} END; WRITELN; WRITE('SEGUIMOS (S/N)? : '); READ(CH) UNTIL (CH='N') OR (EOF(ENT)); CLOSE(ENT) END; (3) PROCEDURE AGREGAR; {AGREGAR modifica el archivo INFO.DAT agregando al final de éste los registros que se deseen} BEGIN OPEN(ENT,INFO.DAT,OUTPUT); RESET(ENT); {prepara lectura del archivo} REPEAT GET(ENT) {avanza hasta el final del archivo} UNTIL EOF(ENT); LEER END; Prof. Leopoldo Silva Bijit. 07-07-2003 286