pii moduloi archivos v3

23
INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763) Programación 2 / Módulo I Pág. 1 POGRAMACIÓN II Año 2008 MÓDULO I ......................................................................................................................................... 2 Introducción ....................................................................................................................................................................................... 3 Archivos .............................................................................................................................................................................................. 3 ¿Qué son los archivos? ................................................................................................................................................................. 3 ¿Para qué uso un archivo? ........................................................................................................................................................... 3 Organización de Archivos .............................................................................................................................................................. 4 Modo de Acceso ................................................................................................................................................................................ 4 Archivos Secuenciales .................................................................................................................................................................... 4 Lectura y grabación de datos ........................................................................................................................................................ 5 Operaciones básicas con archivos .............................................................................................................................................. 5 Abrir archivo .................................................................................................................................................................................... 6 Abrir archivo para lectura ......................................................................................................................................................... 6 Abrir archivo para escritura ...................................................................................................................................................... 7 Determinar la condición de fin de archivo (EOF) ....................................................................................................................... 7 Leer un registro ............................................................................................................................................................................... 7 Grabar un registro .......................................................................................................................................................................... 8 Cerrar el archivo ............................................................................................................................................................................. 8 Procesamiento de datos ................................................................................................................................................................ 9 Corte de Control .............................................................................................................................................................................. 11 Apareo de Archivos ........................................................................................................................................................................ 16 Síntesis del Módulo I ...................................................................................................................................................................... 22 Autoevaluación ................................................................................................................................................................................ 22 Elaboración Carlos Bruschetti Nelson Ciffoni Este material pertenece a la materia Programación II, de la Carrera de Analista de Sistemas de Computación del INSTITUTO DE TECNOLOGÍA ORT. Todos los derechos reservados. No esta permitida la reproducción total o parcial de este apunte, ni su tratamiento informático, ni la transmisión de ninguna forma o por cualquier medio, ya sea electrónico, mecánico, por fotocopia, por registro u otros métodos, sin el permiso previo de los titulares. 1ra edición Diciembre de 2007.

Upload: javierguerrero6

Post on 21-Jun-2015

154 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 1

POGRAMACIÓN II Año 2008

MÓDULO I .........................................................................................................................................2

Introducción .......................................................................................................................................................................................3

Archivos ..............................................................................................................................................................................................3 ¿Qué son los archivos? .................................................................................................................................................................3 ¿Para qué uso un archivo? ...........................................................................................................................................................3

Organización de Archivos ..............................................................................................................................................................4

Modo de Acceso ................................................................................................................................................................................4

Archivos Secuenciales ....................................................................................................................................................................4

Lectura y grabación de datos ........................................................................................................................................................5 Operaciones básicas con archivos ..............................................................................................................................................5 Abrir archivo ....................................................................................................................................................................................6 Abrir archivo para lectura .........................................................................................................................................................6 Abrir archivo para escritura ......................................................................................................................................................7

Determinar la condición de fin de archivo (EOF).......................................................................................................................7 Leer un registro...............................................................................................................................................................................7 Grabar un registro ..........................................................................................................................................................................8 Cerrar el archivo .............................................................................................................................................................................8 Procesamiento de datos................................................................................................................................................................9

Corte de Control ..............................................................................................................................................................................11

Apareo de Archivos........................................................................................................................................................................16

Síntesis del Módulo I......................................................................................................................................................................22

Autoevaluación................................................................................................................................................................................22

Elaboración

Carlos Bruschetti

Nelson Ciffoni

Este material pertenece a la materia Programación II, de la Carrera de Analista de Sistemas de Computación del INSTITUTO DE TECNOLOGÍA ORT. Todos los derechos reservados. No esta permitida la reproducción total o parcial de este apunte, ni su tratamiento informático, ni la transmisión de ninguna forma o por cualquier medio, ya sea electrónico, mecánico, por fotocopia, por registro u otros métodos, sin el permiso previo de los titulares. 1ra edición Diciembre de 2007.

Page 2: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 2

MÓDULO I Introducción y orientaciones para el estudio En el desarrollo de este módulo abordaremos: � Conceptos generales de archivos � Procesamiento de archivos secuenciales � Técnica de Corte de control � Procesos de apareo de archivos secuenciales Objetivos Pretendemos que al finalizar de estudiar esta Unidad, el alumno logre: � Comprender la comunicación entre la memoria de la computadora y los dispositivos de

almacenamiento permanente. � Aplicar la técnica de corte de control y el proceso de apareo de archivos secuenciales para

la resolución de problemas. Aclaraciones previas al estudio En este módulo, usted encontrará: Contenidos Conceptualizaciones centrales Bibliografía Referencia de material bibliográfico recomendado Actividades

Usted debe tener presente que los contenidos presentados en el módulo no ahondan profundamente en el tema, sino que pretenden ser un recurso motivador, para que a través de la lectura del material, la bibliografía sugerida, y el desarrollo de las actividades propuestas alcance los objetivos planteados en el presente módulo. Cada módulo constituye una guía cuya finalidad es facilitar su aprendizaje.

Page 3: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 3

Introducción

En este módulo vamos a trabajar con archivos. Qué es un archivo y para qué sirve. Cuáles son sus usos más corrientes. Mencionaremos los distintos tipos de organización de archivos y nos centraremos en los archivos de organización secuencial.

También revisaremos las operaciones básicas sobre archivos, el tema del procesamiento de datos y la técnica de programación llamada corte de control. Por último analizaremos el proceso de apareo de archivos secuenciales y desarrollaremos una estrategia de solución.

Archivos

¿Qué es un archivo? ¿Para qué uso un archivo?

Estas son algunas preguntas que nos hacemos cuando comenzamos a abordar el tema del manejo de archivos.

¿Qué son los archivos? Es un grupo de datos estructurados, que son almacenados en un medio magnético, y puede ser accedido para su uso por medio de una computadora.

Hablamos de grupo de datos estructurado. Generalmente cada componente de este grupo de datos se denomina registro. Entendemos un archivo como una sucesión lógica de registros.

A su vez un registro está formado por campos y constituye una unidad de información (referida por ejemplo a un cliente, a un alumno, etc.). Estos campos son la unidad mínima de información del registro. Estos campos se diferencian por el significado o sentido dado a cada uno.

Si el dato correspondiente un campo de un registro no toma el mismo valor para registros distintos (por ejemplo el N° de matrícula en un archivo que contiene los alumnos de un determinado curso), diremos que la factibilidad es 0 o 1 para el N° de matrícula. Esto significa que un N° de matrícula dado puede aparecer a los sumo en un registro del archivo.

Hablamos de factibilidad 0/N para un campo, si en el archivo puede haber hasta N registros con el mismo valor para ese campo. Por ejemplo el campo Nota para un archivo de alumnos de un curso tiene factibilidad 0/N.

¿Para qué uso un archivo? Generalmente, un archivo es usado para acceder a información que se usa frecuentemente, o para almacenar un gran volumen de información que va a ser usada por distintas personas o distintas áreas de una organización.

Encontramos a nuestro alrededor varios ejemplos de utilización de archivos: los archivos de errores o de “log”, es un ejemplo conocido en los ámbitos informáticos; la información de un padrón electoral, se encuentra en un archivo, donde cada registro corresponde a una persona con todos sus datos (documento de identidad, domicilio, ocupación, etc.); el listado de alumnos de una facultad también se encuentra en un archivo.

Page 4: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 4

Organización de Archivos

El término organización de archivos se aplica a la forma en que se estructuran los registros sobre el soporte magnético (disco, cinta,..) durante su grabación.

Podemos hacer una breve enumeración de las formas básicas de organización de archivos: secuencial, relativa y secuencial indexada.

En la organización secuencial los registros se van grabando unos a continuación de los otros, en el orden que se van dando de alta, mientras que en la organización relativa los registros se graban en las posiciones que les corresponda según el valor que guarden en el campo clave.

El campo clave permite identificar unívocamente al registro. Ejemplos de campos clave son el DNI para un archivo de personas, el código para archivos de productos o clientes, la matrícula para archivos de alumnos.

En la organización secuencial indexada los registros se graban inicialmente en forma secuencial, y además se utilizan tablas que permiten localizar un registro de acuerdo a su clave; además se utilizan espacios de almacenamiento para guardar registros que se agregan y no pueden ubicarse secuencialmente.

La forma en que se organiza un archivo determina el modo de acceso al mismo.

Modo de Acceso

El modo de acceso se refiere al procedimiento que se debe seguir para situarse en un registro determinado para realizar una operación de lectura o grabación del mismo.

El modo de acceso puede ser secuencial o directo. En el modo de acceso secuencial para llegar a un registro es necesario pasar por todos los anteriores, mientras que en el modo de acceso directo se puede llegar directamente a un registro conociendo únicamente el valor del campo clave.

El modo de acceso directo se puede llevar a cabo de varias formas:

1. La posición que ocupa el registro dentro del fichero coincide con el contenido de la clave.

2. Calculando la posición que ocupa el registro en el fichero mediante una transformación del contenido del campo clave (acceso aleatorio - Hashing).

3. Mediante el uso de tablas de índices. La localización de un registro se hace buscando en la tabla de índices el valor del campo clave y obtenemos la posición en que está grabado el registro dentro del fichero (acceso indexado - Keyed).

Para decidir cuál es la mejor organización hay distintos criterios a tener en cuenta: rápido acceso, fácil actualización, economía de almacenamiento, fácil mantenimiento.

Archivos Secuenciales

La organización secuencial es la forma más simple de almacenamiento de información en un medio magnético. Los registros están organizados de manera secuencial, es decir uno detrás del otro y con una marca a continuación del último que indica el final del archivo. Esta marca se la conoce con el nombre de End Of File (EOF).

La lectura se realiza desde el primer registro, pasando por cada uno de los restantes hasta llegar al final, sin posibilidad de retroceder en el recorrido, o de saltear aleatoriamente algún registro.

Page 5: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 5

Este tipo de organización no permite la eliminación de registros ni la inserción en cualquier lugar, salvo al final. Para poder resolver la inserción de registros se utilizan algoritmos llamados apareo de archivos que a partir del archivo original y un archivo de novedades generan un nuevo archivo actualizado que luego reemplazará al original.

Los archivos de organización secuencial se utilizan típicamente para el procesamiento de datos por lotes, o procesamiento batch, donde todos los registros deberán ser procesados. También suelen utilizarse en procesos donde se debe almacenar la información a medida que se recibe para que posteriormente otro programa la analice, es por ejemplo el caso de los archivos de log donde se guarda cronológicamente información acerca de alguna actividad.

Lectura y grabación de datos

Para trabajar con archivos en el lenguaje de programación C++, debemos contar con 2 variables. En la primera de ellas se almacenará la información acerca de la ubicación del archivo en el dispositivo magnético, y la segunda variable deberá ser una estructura en donde se almacenarán los datos del registro del archivo.

Antes de comenzar a hablar de estas variables, vamos a hacer una pequeña referencia al concepto de puntero; más adelante lo profundizaremos.

¿Qué es un puntero? Un puntero (o apuntador) es una variable que hace referencia a una región de memoria; en otras palabras es una variable cuyo contenido es una dirección de memoria.

En el caso de lectura y grabación de archivos, decimos que contamos con dos variables. La primera de ellas es un puntero que indica la posición en el medio magnético donde se va a realizar la operación de lectura o de escritura. O sea, este puntero indica dónde se encuentra el próximo registro a leer, en el caso en que estemos leyendo datos del archivo, o dónde se grabará el siguiente registro, en el caso que estemos escribiendo datos.

Este puntero es la variable que relaciona la ubicación física del archivo (en el medio magnético), con el nombre lógico con el que se identifica el archivo en el programa. Cuando el programa hace referencia al nombre lógico, el sistema interpreta esta asociación y sabe el lugar físico del dispositivo magnético donde debe leer o grabar.

La otra variable deberá ser una estructura que almacenará un registro del archivo. En el caso de leer datos, esta variable recibirá el registro que acabamos de leer y en el caso de escribir, debemos asignarle los datos que queremos guardar en el archivo.

Operaciones básicas con archivos Para operar con archivos, es necesario conocer algunas operaciones básicas para el manejo de los mismos. Las operaciones que soportan la mayoría de los lenguajes de programación son:

Abrir archivo, Cerrar archivo, Grabar registro, Leer registro, Fin de archivo, Borrar registro (no se usa en archivos secuenciales).

A continuación comentamos y desarrollamos estas operaciones; los tipos de dato usados no están declarados en C++ aunque sus nombres son suficientemente “explicativos”, dejamos al lector esta tarea.

Page 6: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 6

Abrir archivo

Abrir archivo para lectura

void AbrirArchivoDatos (srt40 ubicacion, str2 tipoApertura, File * &ArchivoDatos, bool &pudeAbrir)

En el procedimiento de apertura de archivos, pasamos 4 parámetros:

Ubicación indica el nombre físico del archivo (el nombre que tiene en el medio magnético).

TipoApertura indica en qué forma se va a abrir este archivo. Si vamos a abrir el archivo en modo “lectura” , debemos indicar si la lectura se hará sobre un archivo de texto (rt, read text), o sobre un archivo binario (rb, read binary).

ArchivoDatos es el puntero que va a ir moviéndose por el archivo. En el momento de la apertura, en modo lectura, el puntero se sitúa en el primer registro del archivo.

PudeAbrir es una variable booleana, que retornará TRUE si fue posible abrir el archivo, o FALSE en el caso de no poder abrirlo. Generalmente, los casos en que falla la apertura del archivo, es porque no se encontró el archivo en el lugar físico que se indicó.

Nota: En esta asignatura, y para simplificar los diagramas asumiremos que siempre es posible abrir el archivo, dejando para la práctica en máquina este control.

La implementación de esta rutina en lenguaje C++ sería de la siguiente forma:

void AbrirArchivoDatos (srt40 ubicacion, str2 tipoApertura, File * &ArchivoDatos, bool &pudeAbrir) { ArchivoDatos = fopen (ubicacion, tipoApertura); if (ArchivoDatos == NULL) { cout << "No se pudo Abrir el Archivo de Datos\n"; pudeAbrir = FALSE; } else { pudeAbrir = TRUE; } }

Y la llamada o invocación en el diagrama seria, por ejemplo:

Page 7: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 7

Abrir archivo para escritura

void AbrirArchivoDatos (srt40 ubicacion, str2 tipoApertura, File * &ArchivoDatos, bool &pudeAbrir)

En el caso que abramos un archivo para grabar datos, la variable puntero ArchivoDatos recibirá la información del lugar donde se grabará el próximo registro y creará una entrada en el dispositivo magnético para el nuevo archivo, con el nombre pasado en el parámetro ubicacion.

El parámetro tipoApertura ahora indica si se grabará un archivo de texto (wt) o un archivo binario (wb).

Generalmente, los casos en que falla la apertura de un archivo, es porque no encontró el archivo en el lugar físico indicado, o porque el dispositivo magnético se encontraba protegido contra escritura.

El desarrollo del procedimiento y la llamada en el diagrama son los mismos que para lectura.

ATENCIÓN: Cuando se abre un archivo para escritura, en el caso que el archivo ya exista, se reemplazará por el nuevo, perdiendo el anterior.

Determinar la condición de fin de archivo (EOF) Para determinar la condición de fin de archivo cada vez que se realiza una lectura del archivo hay que evaluar si devolvió la marca de fin de archivo (EOF) o los datos en la estructura del registro.

Esto se puede implementar con una variable booleana que devolverá TRUE en el caso que encuentre la marca de EOF, o FALSE en caso contrario.

En lenguaje C++ contamos con una función llamada feof que evalua la condición de fin de archivo, y devuelve 0 si está sobre la marca de fin de archivo y 1 si no lo está.

int feof(ArchivoDatos)

Leer un registro void LeerArchivoDatos (FILE * &aDatos, ty_reg &sRegDatos, bool &bFin)

Page 8: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 8

En el procedimiento de lectura de archivos, pasamos 3 parámetros:

aDatos es el puntero al archivo a leer

sRegDatos variable con la estructura del registro del archivo, es el patrón para leer el archivo. En esta variable el procedimiento de lectura entrega el registro leído.

bfin indica si el archivo llegó al final, o sea, si encontró la marca de EOF (TRUE), o no.(FALSE)

La implementación de esta rutina en lenguaje C++ sería de la siguiente forma:

void LeerArchivoDatos (FILE * &aDatos, ty_reg &sRegDatos, bool &bFin) { fread (&sRegDatos, sizeof(ty_reg), 1, aDatos); if feof (aDatos) bFin = TRUE; else bFin = FALSE; }

Grabar un registro void GrabarRegistroDatos (FILE * &aDatos, ty_reg sRegDatos)

En el procedimiento de escritura de archivos, pasamos sólo 2 parámetros:

aDatos es el puntero al archivo a leer

sRegDatos variable con la estructura del registro del archivo, es el patrón para grabar el archivo. En esta variable se almacenan los datos a grabar en el archivo.

La implementación de esta rutina en lenguaje C++ sería de la siguiente forma:

void GrabarRegistroDatos (FILE * &aDatos, ty_reg sRegDatos) { fwrite (&sRegDatos, sizeof(ty_reg), 1, aDatos); }

Cerrar el archivo void CerrarArchivoDatos (FILE * &aDatos)

Page 9: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 9

La implementación de esta rutina en lenguaje C++ sería de la siguiente forma:

void CerrarArchivoDatos (FILE * &aDatos) { fclose (aDatos); }

Cuando se cierra un archivo, éste queda no disponible para su uso en el programa. Esta operación “corta” el vínculo establecido entre el programa que usa el archivo y los datos almacenados en una memoria externa o auxiliar (el archivo); también se graba en el archivo el último bloque que está en memoria.

Procesamiento de datos Al momento de procesar los datos almacenados en un archivo, debemos leer y procesar un registro por vez, de la misma forma que lo haríamos si los datos se ingresan por teclado.

Para poder controlar el fin del archivo debemos leer la marca de EOF y de esa manera controlar el ciclo de lectura.

Como cada lenguaje de programación maneja a su manera el EOF, vamos a generalizar la solución utilizando un procedimiento para la lectura de los datos, como vimos en el ejemplo anterior, que se encargará de controlar una variable booleana que indicará el fin del archivo.

A continuación veamos un ejemplo de lectura y escritura de archivos.

Supongamos un programa que lee desde un archivo los datos de inscripción de un alumno, y que luego de validarlos, si la validación es OK lo graba en el maestro de alumnos, y si la validación es errónea, lo graba en un archivo de errores. De esta forma, podemos utilizar el mismo procedimiento Grabar ya que el formato del registro es el mismo tanto para el archivo de datos de inscripción, como para el archivo de errores.

Mostraremos primero los prototipos de los procedimientos que vamos a utilizar, y a continuación el diagrama de este proceso.

Suponemos declarados las variables y tipos correspondientes, los nombres que utilizamos son suficientemente representativos.

/*Declaración de prototipos*/

void AbrirArchivo (srt40 ubicacion, str2 tipoApertura, File * &ArchivoDatos, bool &pudeAbrir)

void LeerregistroNovedades (FILE * &Arch, ty_reg &registro, bool &bFin)

int validoNovedades (ty_reg registro)

void GraboArch (FILE * &Arch, ty_reg registro)

void CerrarArchivo (FILE * &Arch)

Page 10: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 10

El procedimiento será el siguiente:

Archivos de Entrada

Archivo de Salida

El formato del registro

es el mismo para el

archivo de entrada y

el archivo de salida

AbrirArchivo (sUbicNov, “rb”, aNovedad, bPude)

AbrirArchivo (sUbicMae, “wb”, aMaestro, bPude)

AbrirArchivo (sUbicErr, “wb”, aErrores, bPude)

!bFinNov

GrabarArchivo (aMaestro,

RegNov)GrabarArchivo (aErrores,

RegNov)

LeerRegistroNovedades (aNovedad, RegNov, bFinNov)

LeerRegistroNovedades (aNovedad, RegNov, bFinNov)

CerrarArchivo (aNovedad)

CerrarArchivo (aMaestro)

CerrarArchivo (aErrores)

Si observamos el diagrama, existen dos llamadas al procedimiento de lectura, la primera es la llamada para leer el primer registro del archivo que de existir nos permitirá entrar en el ciclo para procesarlo y continuar leyendo el resto.

En caso que el archivo esté vacío, la variable bFinNov volverá con TRUE y por lo tanto no entraremos al ciclo; a continuación veremos la importancia de esta primer lectura adelantada.

Aclaración: De aquí en adelante, y por una cuestión de simplicidad en el procedimiento para abrir un archivo, indicaremos sólo el modo de apertura y el nombre lógico del archivo, omitiendo el nombre físico. Por ejemplo:

AbrirN (“rb”, aNotas)

Abre para lectura en forma binaria el archivo aNotas.

Es importante recordar que en la implementación es necesario indicar también la ubicación del archivo y pasar el parámetro lógico o booleano para indicar si fue posible abrir el archivo o no.

En este contexto asumimos que siempre es posible abrir el archivo.

Page 11: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 11

Corte de Control

El corte de control es una técnica de programación muy utilizada que permite resolver determinadas situaciones en las cuales es necesario agrupar los registros almacenados en el archivo de acuerdo a la información almacenada en uno o más campos.

Remontándonos a un ejercicio típico de Algoritmos y Estructura de Datos I, supongamos el siguiente enunciado:

Confeccionar un programa que procese la información de las ventas de una distribuidora de chocolates que tiene 20 sucursales en todo el país y cuenta con 10 vendedores como máximo en cada sucursal. Para ello nos informan por cada venta realizada, los siguientes datos:

• Nro Factura (15 Caracteres)

• Cod Sucursal (Entero)

• Nro vendedor (Entero)

• Importe (Real).

El programa debe informar:

• Para cada sucursal, cuál fue el importe total vendido por cada vendedor.

• Cuál fue la sucursal que más vendió.

Una solución a este ejercicio sería armar una matriz de 20 filas que representarán a las sucursales, por 10 columnas que representarán a los vendedores y por cada venta ingresada se actualizará una celda de la matriz acumulando el importe vendido.

De esta manera tendríamos toda la información para que al finalizar el proceso, recorriendo la matriz podamos mostrar los resultados pedidos.

Ahora supongamos que en lugar de ese enunciado tenemos este otro:

Confeccionar un programa que procese la información de las ventas de una distribuidora de chocolates que tiene sucursales en todo el país. Para ello nos informan por cada venta realizada y ordenado por sucursal y vendedor, los siguientes datos:

• Nro Factura (15 Caracteres)

• Cod Sucursal (Entero)

• Nro vendedor (Entero)

• Importe (Real)

El programa debe informar:

• Para cada sucursal, cuál fue el importe total vendido por cada vendedor.

• Cuál fue la sucursal que más vendió.

A diferencia del ejercicio anterior, no contamos con la información de cuántas sucursales y vendedores hay; por lo que nos resultará imposible ir acumulando la información de las ventas en una matriz dado que no podemos dimensionarla. Pero nos informan que “los datos están ordenados por sucursal y vendedor” y esta es la clave para poder resolver el problema.

Page 12: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 12

En el caso en que la información esté ordenada por el mismo criterio que nos están pidiendo informar, se puede aplicar la técnica de corte de control para agrupar los datos y de esta manera poder informar de acuerdo a lo pedido.

Supongamos el siguiente juego de datos para procesar:

Como podemos observar, si los datos están ordenados, todas las ventas del vendedor 1 de la sucursal A van a estar juntas, por lo tanto podríamos tener una única variable para acumular las ventas de los vendedores.

Esta variable la inicializaríamos en 0 antes de procesar las ventas del vendedor 1 de la sucursal A y cuando cambia el vendedor, mostramos lo que acumulamos en esa variable, que para el ejemplo sería 83, y la volvemos a poner en 0 para acumular las ventas del siguiente vendedor.

De esta forma, nos alcanza con tener una única variable para todos los vendedores, no importa cuántos fuesen.

Lo mismo podríamos hacer para las sucursales, si queremos saber cuál es la sucursal que más vendió, podemos tener una variable que mientras la sucursal que leemos sea la A, vaya acumulando las ventas y cuando aparece una nueva sucursal, comparamos el acumulado de esa sucursal con el máximo que tenemos hasta el momento (reemplazándolo si corresponde) y volvemos a inicializar la variable para hacer lo mismo con las siguiente sucursal.

Page 13: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 13

Esta técnica de resolución es la que llamamos corte de control y se implementa de la siguiente manera:

Cada grupo o jerarquía que necesitemos procesar, va a necesitar de un ciclo donde procesemos los datos de ese grupo, luego, para controlar este ciclo necesitaremos una variable que previamente reciba el valor actual del dato por el cual queremos agrupar y en cada vuelta del ciclo vamos a estar comparando el nuevo dato leído con el contenido de esta variable para ver si cambió.

Al comenzar cada ciclo, deberemos inicializar también todas las variables que necesitamos para ese grupo y al finalizar cada ciclo mostraremos los resultados de la actualización de esas variables.

Cada uno de estos ciclos que armamos y anidamos se llama nivel del corte de control y como dijimos antes que cada agrupamiento necesita de un ciclo, vamos a tener tantos niveles de corte como agrupamientos sean necesarios.

En el ejemplo anterior en el que tenemos que agrupar por sucursal y vendedor vamos a tener 2 niveles de corte de control.

A continuación el esquema clásico de un corte de control de 2 niveles:

Aclaración: Vamos a notar que en algunos procedimientos hay “puntos suspensivos”. Esto se debe a que como es un diagrama genérico, se indican con puntos suspensivos los parámetros que se pasarían en cada llamada a un procedimiento de acuerdo a un problema dado.

Page 14: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 14

InicioGeneral (bFin, …)

AbrirDatos (aDatos, “rb”)

LeerArch (aDatos, sReg, bFin)

!bFin

clave1Ant sReg.clave1

InicioCorte1 (…...)

(!bFin) && (clave1Ant == sReg.clave1)

clave2Ant sReg.clave2

InicioCorte2 (…...)

(!bFin) && (clave1Ant == sReg.clave1) &&

(clave2Ant == sReg.clave2)

Proceso de los Datos (…...)

LeerArch (aDatos, sReg, bFin)

FinCorte2 (…...)

FinCorte1 (…...)

Cerrar (aDatos)

FinGeneral (….…)

Observemos que:

� En el diagrama vemos 3 ciclos mientras, el primero es para controlar el fin de los datos y los dos siguientes para los 2 niveles de corte.

� Previo a cada nivel de corte existe un procedimiento para inicializar todas las variables correspondientes a ese nivel y al final existe otro procedimiento para utilizar los resultados obtenidos dentro del corte. Los resultados se pueden informar por pantalla, imprimir mediante una impresora o grabarse en un archivo para otro proceso.

A continuación el diagrama de la solución al ejercicio aplicando corte de control:

Page 15: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 15

Para poder aplicar la técnica de corte de control, los datos deben estar ordenados por los campos que queremos agrupar.

• Se debe utilizar el esquema de lectura adelantada para que con la primera lectura se puedan inicializar las variables que guardan los datos anteriores.

• La primera lectura debe hacerse fuera de todo ciclo y las siguientes siempre en el ciclo más interno.

• Cada nivel de corte está compuesto de 3 partes, la inicialización de todas las variables a utilizar en ese nivel, el ciclo donde procesamos los datos y el fin del corte donde se utilizan los datos almacenados en las variables que se inicializaron y procesaron previamente.

• A medida que se agregan niveles de corte, las condiciones de los ciclos mientras (while) se van sumando. En el primer ciclo, que es el que controla el fin de los datos, solo tenemos la condición de fin de ciclo. En el siguiente ciclo, que corresponde al primer nivel de corte, debemos controlar que no cambie el dato por el cual estamos agrupando, pero también que nos e terminen los datos. Y así sucesivamente.

Page 16: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 16

Actividades:

• Realizar el seguimiento del diagrama de corte de control con los datos de prueba y analizar los resultados

Apareo de Archivos

El apareo de archivos es un proceso muy común en archivos secuenciales, en el cual se trabaja con dos o más archivos de entrada, que deben estar ordenados por la misma clave (campo del registro). La característica principal de este proceso, es que una vez procesados los archivos que intervienen en el apareo, en general queda como resultado un solo archivo, producto del procesamiento de los archivos de entrada.

Son procesos de apareo:

� Intercalación o mezcla (merge): a partir de dos archivos de igual estructura, ordenados por un mismo campo, se obtiene un archivo que contiene los registros de ambos y que mantiene el ordenamiento.

Por ejemplo: Obtener un archivo único de asistentes a un evento, ordenado por DNI, a partir de la información registrada en cada una de las 2 entradas habilitadas. Notar que tanto los archivos de entrada, como el resultante estarán ordenados por DNI y tendrán factibilidad 0/1 por ese campo.

� Intersección: a partir de dos archivos de igual estructura, se obtiene un archivo en el que figuran todos los registros comunes a ambos, (también podrían ser los no comunes).

Por ejemplo: Generar el archivo de personas que obtuvieron su registro de conductor, a partir de la información almacenada en los 2 archivos donde se grabaron los datos de las personas que aprobaron el examen teórico y el examen práctico respectivamente. Notar que tanto los archivos de entrada, como el resultante estarán ordenados por DNI y tendrán factibilidad 0/1 por ese campo. El archivo de salida tendrá un registro por cada persona cuyos datos figuraban en ambos archivos de entrada (aprobó el examen teórico y el práctico).

� Actualización: se procede a la actualización de uno o más campos, a partir de un archivo maestro y un archivo de novedades, ambos ordenados por el mismo campo (aunque no necesariamente con la misma estructura de registro). Como resultado del proceso se genera un archivo maestro actualizado. Observar que la cantidad de novedades para cada registro del maestro puede ser ninguna, 1 o varias, dependiendo del proceso (factibilidad 0/n), mientras que el campo clave del archivo maestro a actualizar tendrá factibilidad 0/1.

Por ejemplo: Actualizar el archivo de los alumnos de un curso, cargando las notas parciales entregadas por los profesores. En este caso el archivo de alumnos es el maestro y tendrá factibilidad 0/1 por Número de matrícula. A su vez, en el archivo con las novedades de las notas, para cada alumno se podrán informar ninguna, 1 o más notas parciales (factibilidad 0/n por Número de matrícula, donde n es la cantidad de notas informadas para un alumno). Notar que ambos archivos de entrada (maestro y novedades), deben estar ordenados por Número de matrícula para posibilitar el apareo (todas las notas para un alumno vienen “juntas”). El archivo de salida del proceso (archivo de alumnos actualizado contendrá la misma cantidad de registros que el archivo de alumnos leído y tendrán factibilidad 0/1 por ese campo.

Page 17: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 17

Si bien en este módulo no abordaremos en detalle este problema, que será motivo de análisis más adelante, mencionamos que un ejemplo clásico de apareo de archivos son los famosos ABM de novedades, donde se procesan las Altas, Bajas y Modificaciones sobre un archivo maestro. Dichas Altas, Bajas y Modificaciones vienen informadas en un archivo de novedades, ordenadas por la misma clave que el archivo maestro. La clave es el campo que permite identificar el registro.

En este proceso, el archivo resultante es un archivo maestro actualizado, y si corresponde, un archivo con los errores del proceso. El archivo maestro actualizado puede contener registros nuevos (altas), registros modificados y también no contener registros que estaban en el maestro de entrada por haber sido dados de baja.

En un proceso de apareo de actualización, se puede actualizar cualquier campo, menos el campo clave.

Analizaremos un proceso de apareo mediante la resolución del siguiente problema:

Las inscripciones para concurrir a una conferencia deben realizarse personalmente en alguna de las dos sedes habilitadas a tal fin, una en la ciudad de Buenos Aires y otra en la ciudad de La Plata. En cada sede se han registrado los inscriptos consignando para cada uno: número de DNI, apellido y nombre, teléfono y mail. Ambos archivos de inscriptos son ordenados por DNI (tienen factibilidad 0/1 por este campo), y remitidos para su procesamiento.

Debemos obtener un archivo de inscripción, ordenado por DNI, que también tendrá factibilidad 0/1 por este campo, con todas las personas inscriptas. Si una persona se anotó en ambas sedes, debe tener un solo registro en el archivo de inscripción unificado.

Comenzamos por declarar las estructuras necesarias para la resolución del problema y luego analizaremos la estrategia de resolución y completaremos si es necesario.

//suponemos declarados con typedef los tipos str20 y str15 como cadenas de caracteres de la longitud indicada.

// estructura del registro para los 3 archivos

typedef struct ty_rInsc{

int DNI;

str20 ApyN;

str15 mail;

str15 tel;

}

Ahora declaramos los registros y los archivos

void main() {

FILE * aInscBA; //archivo de inscriptos en BA

FILE * aInscLA; //archivo de inscriptos en La Plata

FILE * aInscU; //archivo de inscripción unificado

Page 18: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 18

ty_rInsc rInscBA; // para leer el archivo aInscBA

ty_rInsc rInscLP; //para leer el archivo aInscLP

Para resolver el problema, obviamente comenzaremos por abrir los archivos aInscBA y aInscLP para lectura y aInsc para grabación. Luego iremos leyendo los registros de ambos archivos de entrada, ordenados por DNI, volcando en el archivo de salida los registros de inscripción de forma tal que resulten ordenados por DNI y que no haya registros repetidos en el archivo de salida.

Por el momento postergamos la cuestión de cómo controlar el fin del proceso, aunque sabemos que nuestro trabajo terminará cuando no haya más registros para leer en ninguno de los 2 archivos de entrada.

Comenzaremos por leer un registro de cada archivo de entrada, la idea es ir procesando “simultáneamente” los archivos aInscBA y aInscLP, comparando las claves del registro de cada uno y obrando en consecuencia.

Analicemos qué significan los posibles resultados de comparar rInscBA.DNI con rInscLP.DNI.

(1) Si rInscBA.DNI < rInscLP.DNI � La persona se inscribió en Buenos Aires

Debemos:

grabar el registro rInsBA en el archivo aInscU

leer un registro del archivo aInscBA

(2) Si rInscBA.DNI > rInscLP.DNI � La persona se inscribió en La Plata

Debemos:

grabar el registro rInscLP en el archivo aInscU

leer un registro del archivo aInscLP

(3) Si rInscBA.DNI == rInscLP.DNI � La persona se inscribió en Buenos Aires y en La Plata

Debemos:

grabar el registro rInscBA en el archivo aInscU (notemos que en este caso es indistinto desde qué registro de entrada grabar ya que ambos tienen el mismo DNI, corresponden a la misma persona, y no tiene sentido inscribirla 2 veces)

leer un registro del archivo aInscBA

leer un registro del archivo aInscLP

Las acciones indicadas en la tabla anterior deberán realizarse mientras haya registros (esto es inscriptos) en alguno de los 2 archivos de entrada.

¿Qué debemos hacer si no hay más inscriptos en el archivo de aInscLP, pero quedan inscriptos en aInscBA?

Piense ANTES de continuar leyendo…

Page 19: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 19

Debemos grabar todos los registros restantes del archivo aInscBA en el archivo de salida (aInsc), procediendo como en (1) del cuadro anterior, hasta alcanzar el fin del archivo aInscBA.

Análogamente si no hubiera más inscriptos en el archivo aInscBA, pero quedaran registros sin procesar en aInscLP, estos registros deberían grabarse en el archivo aInsc, procediendo como en el caso (2) del cuadro anterior.

Por último, si se alcanza el fin de archivo en ambos archivos de entrada simultáneamente, es porque los últimos registros de cada uno tienen igual DNI, caso (3) del cuadro anterior.

Retomamos aquí la cuestión del control del fin del proceso; por lo visto recién, si al alcanzar el fin de uno de los archivos de entrada, asignáramos al campo DNI (clave) de su registro un valor suficientemente grande (por ejemplo en este caso 999999999), el DNI de los registros del archivo que no finalizó resultaría siempre menor que este valor. Por lo tanto se grabaría el archivo de salida y se volvería a leer del archivo que aun tiene registros, y así hasta alcanzar el fin de este archivo también.

Si cuando se alcanza el fin del archivo que termina en segundo lugar, procedemos de la misma forma, asignando un valor suficientemente grande al campo DNI, ya tenemos la condición que controla el ciclo del proceso de apareo.

Mientras que alguno de los archivos no haya alcanzado el fin, continuamos ciclando, y recién salimos cuando ambas claves tienen el valor 999999999, cuando ambos archivos alcanzaron el fin:

(rInscBA.DNI != 999999999) || (rInscLP.DNI != 999999999)

Ejecutar las acciones indicadas en la tabla anterior, esto es, comparar las claves de los registros leídos y obrar en

consecuencia.

Ahora sólo restaría cerrar todos los archivos del proceso.

Observemos que será necesario modificar el procedimiento de lectura, ya que en este caso no devolverá un valor lógico o booleano indicando si se alcanzó el fin de archivo. En caso de alcanzar el fin del archivo asignará ese valor suficientemente grande al campo clave del registro.

Ese valor suficientemente grande que asignamos al campo clave se denomina cota superior. Una cota es un valor que sirve de límite (superior o inferior) para un conjunto de valores, y que no pertenece al conjunto en cuestión.

Una cota superior debe ser mayor que todos los valores posibles del campo que está acotando y de igual forma, una cota inferior debe ser menor que todos los valores posibles del campo.

En este ejemplo, dado que los DNI son cifras de 8 dígitos, el valor 999999999 funciona correctamente como cota superior para el número de DNI. Análogamente el valor 11 podría ser una cota superior para un conjunto de notas (valores entre 0 y 10) y el valor –1 una cota inferior para el mismo conjunto.

Para trabajar correctamente, usaremos un #define para establecer el valor de la COTA, de esta forma ganamos en claridad en la resolución y facilitamos una eventual modificación del valor para la cota. En este caso, debemo escribir antes de las declaraciones ya realizadas:

#define COTA 999999999

Ahora ya podemos escribir el procedimiento de lectura, al que además del archivo y el registro, pasaremos la COTA para asignar al campo clave cuando se detecte el fin de archivo.

Page 20: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 20

Este procedimiento lo usaremos para leer ambos archivos de entrada, ya que tienen registros del mismo tipo, invocándolo en cada caso con los parámetros correspondientes.

void Leer_aInsc (FILE * &arch, ty_rInsc & reg, int iValorcota)

Presentamos el diagrama que expresa la estrategia de solución analizada anteriormente.

Page 21: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 21

Los dos registros

tienen el mismo

DNI

Abrir aSede (aInscBA, “rb”)

Abrir aSede (aInscLP, “rb”)

Abrir aInscU (aInscU, “wb”)

Leer aInsc (aInscBA, rInscBA, COTA)

Leer aInsc (aInscLP, rInscLP, COTA)

(rInscBA.DNI != COTA) || (rInscLP.DNI != COTA)

rInscBA.DNI < rInscLP.DNITrue False

Grabar (aInscU, rInscBA)

Leer aInsc (aInscBA, rInscBA,

COTA)

rInscBA.DNI > rInscLP.DNITrue False

Grabar (aInscU,

rInscBA)

Leer aInsc (aInscBA,

rInscBA, COTA)

Grabar (aInscU,

rInscBA)

Leer aInsc (aInscBA,

rInscBA, COTA)

Leer aInsc (aInscLP,

rInscLP, COTA)

CerraraSede (aInscBA)

CerraraSede (aInscLP)

CerraraSede (aInscU)

Observe que nunca se llamará al procedimiento de lectura para un archivo que alcanzó el fin de archivo. ¿Por qué? Justifique

Piense ANTES de continuar leyendo…

Efectivamente cuando un archivo finaliza, el procedimiento de lectura asigna el valor COTA a la clave del registro. Por lo tanto las claves (DNI en este caso) de los registros del otro archivo siempre resultarán menores; por lo tanto se grabarán en el archivo de salida y se leerá sobre este archivo. Así hasta que este archivo también alcance el fin, en este caso también tendrá COTA en su campo clave y se saldrá del ciclo.

Actividades:

• Realizar el seguimiento del diagrama anterior con los siguientes datos de prueba, analizar como se va avanzando en las lecturas de los archivos de entrada y se genera el archivo resultante. Por simplicidad sólo incluimos los campos DNI y ApyN en los registros del lote de prueba.

archivo aInscBA archivo aInscLP

DNI ApyN DNI ApyN

Page 22: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 22

10123444 Nas, Claudio 10022033 Gral, Federico

13888777 Puig, Matías 10111222 Paez, Jorge

20922333 Lont, Mirta 14666777 Duck, Nicolás

21789789 Kop, Luis 20922333 Lont, Mirta

• Proponer otro lote de prueba, o modificar el anterior para que ambos archivos terminen “simultáneamente” (sugerimos releer el desarrollo de la estrategia de solución).

• ¿Qué ocurre si uno de los 2 archivos de entrada está vacío, esto es, si en alguna de las sedes no se registró ningún inscripto?

• Redactar el enunciado de un problema de apareo de dos archivos secuenciales.

• Pensar y plantear una estrategia de resolución, si en lugar de 2, se leen 3 archivos. Por ejemplo se agrega una sede de inscripción en Tandil. ¿Y si fueran más? Generalizar para más de 3 archivos de entrada.

Síntesis del Módulo I

En este módulo presentamos conceptos básicos sobre qué es un archivo, cómo esta formado, y cuál es su uso más frecuente. También mencionamos las formas de organización de archivos, y trabajamos con mayor grado de detalle con archivos de organización secuencial.

Revisamos las operaciones básicas para el manejo de archivos, asociándolas con las instrucciones de lenguaje C++ para abrir, cerrar, leer y grabar archivos secuenciales.

Formalizamos y ejemplificamos la técnica de programación denominada corte de control, que permite resolver determinadas situaciones en las cuales es necesario agrupar los registros almacenados en un archivo ordenado, de acuerdo a la información almacenada en uno o más campos.

Aprendimos el proceso de apareo de archivos, que permite obtener un archivo actualizado o archivo resultante, a partir del procesamiento de 2 o más archivos ordenados por una misma clave.

Sintetizando podemos expresar que en todo proceso de apareo de 2 archivos secuenciales, A1 y A2, se comparan las claves de 2 registros (1 de cada archivo de entrada, R1 y R2), y los resultados pueden ser 3:

clave R1 < clave R2

clave R1 == clave R2

clave R1 > clave R2

Autoevaluación

Indique si es Verdadera o Falsa cada una de las siguientes afirmaciones

- Entendemos un archivo como una sucesión lógica de registros; los campos de un registro son la unidad mínima de información del mismo, y se diferencian por el significado dado a cada uno, pudiendo ser del mismo o distinto tipo (desde el punto de vista de la programación).

la interpretación de esta relación y la consecuente acción a tomar dependen del problema a resolver.

Page 23: PII ModuloI Archivos v3

INSTITUTO DE TECNOLOGIA O.R.T. Instituto incorporado a la enseñanza Oficial (A-763)

Programación 2 / Módulo I Pág. 23

- En un archivo de organización secuencial la lectura se realiza desde el primer registro, pasando por cada uno de los restantes en forma aleatoria, hasta leer la totalidad de los registros.

- Al momento de procesar los datos almacenados en los archivos, debemos leer y procesar un registro por vez, de la misma forma que lo haríamos si los datos se ingresaran por teclado.

- Para aplicar la técnica de corte de control, los datos deben estar ordenados por el campo más significativo de la estructura del registro.

- En un proceso de corte de control se debe utilizar el esquema de lectura adelantada para que con la primera lectura se puedan inicializar las variables que guardan los datos anteriores.

- En un proceso de apareo, no es necesario que los archivos estén ordenados por el mismo campo.