You are on page 1of 50

Archivos

CAPITULO 14

ARCHIVOS

Introduccin
En el captulo anterior vimos cmo organizar la informacin relativa a una
biblioteca en arreglos de estructuras o bien en arreglos paralelos. Todas las
estructuras de datos vistas hasta ahora, arreglos de una o ms dimensiones y
variavles de estructuras, se almacenan en memoria RAM. Como esta memoria es
voltil, cuando se apaga la computadora toda la informacin almacenada en ella se
borra y por consiguiente tendramos cada vez volver a ingresar toda la
informacin. Esto en impensable en situaciones reales, por ejemplo una biblioteca
que contenga 100000 libros en lugar de 20. Para evitar esto utilizaremos medios de
almacenamiento secundario: las cintas magnticas, los discos rgidos, los discos
flexibles y los discos de almacenamiento ptico son ejemplos de medios de
almacenamiento secundario.
El almacenamiento secundario tiene varias ventajas con respecto a la
memoria RAM: no requieren el suministro continuo de energa elctrica para
conservar la informacin; se puede almacenar ms informacin en estos medios de
la que normalmente puede almacenarse en RAM y es ms econmica. Tales
ventajas no se logran sin dar algo a cambio: el acceso a la informacin del
almacenamiento secundario es mucho ms lento que el acceso a memoria RAM.
Como puede verse guardar la informacin en un disco u otra forma de
almacenamiento secundario tiene sus ventajas y desventajas, por ello la decisin
de qu se guarda y qu no en disco debe hacerse cuidadosamente.

Archivos

Concepto Y Clasificacin De Archivos


La informacin que se guarda en almacenamiento secundario se estructura
en archivos o ficheros. Como los arreglos, los archivos son homogneos: slo
pueden contener un tipo de valores de datos. Los elementos de un archivo pueden
ser de cualquier tipo excepto uno que contenga un archivo.
Existen distintas clasificaciones de archivos. Una primera clasificacin
consiste en definir archivos de texto y binarios. Los primeros son archivos de
caracteres, divididos en lneas de texto como los de una pgina impresa. Estos
archivos tienen la ventaja que pueden verse en pantalla con los comandos que el
sistema operativo tenga para tal fin (type en DOS, cat en UNIX, Block de Notas en
WINDOWS) o bien editarlos con cualquier procesador de texto. La gran
desventaja de estos archivos es que la escritura y lectura con los programas en C o
cualquier otro lenguaje es muy lenta pues deben traducir la informacin en
memoria, que est en binario, a caracteres y viceversa. En los archivos binarios la
informacin se representa con los mismos patrones de bits empleados para
representarla en la memoria principal y por lo tanto no se requiere una traduccin
al leer o escribir. La informacin de los archivos binarios se agrupa, lgicamente,
en registros, entonces podemos definir a un archivo como una coleccin de
registros lgicamente relacionados. Como puede observarse esta definicin no
difiere del concepto que tenamos de arreglos de estructuras o arreglos paralelos.
El tamao de los archivos no se fija a priori como en los arreglos. Un archivo es
una estructura dinmica que aumenta su tamao o lo disminuye a medida que se
ejecuta el programa; el lmite lo fija la capacidad del almacenamiento secundario
(disco, cinta, etc.). Adems un archivo puede ser utilizado por distintos programas,
por ejemplo un programa carga informacin en l y otro la muestra por pantalla.
El concepto de archivo no debe limitarse slo al almacenamiento en discos o
cintas. Tambin son archivos la salida impresa o la entrada de datos a travs de un
lote de tarjetas perforadas. Si bien esto ltimo hoy ha cado en desuso es un buen
ejemplo de un archivo de entrada que no est en disco.
Otra clasificacin de los archivos es: archivos de E/S (entrada/salida),
archivo slo de entrada y archivos slo de salida. Archivos slo de salida (la
informacin se transfiere de la memoria al medio externo) son la impresiones en
papel; archivos slo de entrada (la informacin se transfiere del medio externo a la
memoria) son los lotes de tarjetas perforadas y finalmente los de E/S (la
informacin se transfiere desde el medio externo a la memoria o desde la memoria
al medio externo) son aquellos que pueden leerse y escribirse.
Una tercera clasificacin est dada por la forma en que puede accederse a la
informacin de un archivo: acceso secuencial, acceso directo o secuencial con
ndice. En un archivo secuencial para acceder a un registro debemos pasar por
todos los anteriores a l (como la bsqueda secuencial en un arreglo). Todos los
dispositivos de memoria externa soportan este tipo de acceso pero otros, por su
naturaleza fsica, es el nico que soportan. Cintas magnticas, lectoras de tarjetas
perforadas y las impresoras de lnea son ejemplos de almacenamiento externo que
2

Archivos

slo soportan archivos de acceso secuencial. En los archivos de acceso directo se


puede acceder a cualquier registro sin necesidad de tener que acceder a los
anteriores (de la misma manera que se accede a un elemento de un arreglo).
Podemos leer la informacin contenida en el vigsimo registro sin necesidad de
leer los diecinueve anteriores. Los discos es el medio externo para almacenar estos
archivos. Finalmente los archivos secuencial con ndice slo son soportados por
algunos lenguajes (COBOL y los manejadores de bases de datos). Consideremos
que cada registro de un archivo contiene la informacin relativa a un alumno de la
Universidad (matrcula, nombre, calificacin de primer examen parcial,
calificacin del segundo examen y nota de concepto). Un dato de un registro, que
identifica unvocamente a ste se denomina clave. La matrcula sirve de clave para
este archivo. En una organizacin secuencial con ndice los registros se encuentran
en posiciones consecutivas pero adems existen tablas de ndices esto es tablas que
contienen la clave y el nmero de registro donde se encuentra la informacin
correspondiente al valor de la clave.
En este captulo trataremos, en primer lugar los archivos de texto, luego los
archivos binarios y al final del mismo veremos algunas tcnicas sencillas para
construir archivos ndices.
Archivos De Texto
Un archivo de texto consiste de varias lneas, cada una de las cuales consta
de un nmero variable de caracteres. El concepto es similar a una pgina escrita.
El archivo puede leerse o escribirse ya sea lnea por lnea o carcter por carcter.
Podemos decir que la lectura de un archivo de texto es similar a introducir
informacin va un teclado y que la escritura de un archivo de texto es semejante a
la salida en una pantalla o impresora.
Antes de utilizar un archivo debemos activarlo (abrir el archivo), despus
podemos ya sea leer informacin desde el archivo o escribir en l; por ltimo
cuando terminamos debemos desactivarlo (cerrar el archivo).
En C, para utilizar un archivo debemos, en primer lugar, definir un tipo de
variable especial que se la conoce como puntero a archivo. Un puntero a archivo
es una variable que seala a la informacin que define varias cosas propias del
archivo, entre las que se incluye su nombre, su estado y la posicin actual. La
sintxis para definir una varable puntero a archivo es:
FILE *nombre_de_archivo;
donde nombre_de_archivo se construye de la misma manera que los nombres de
variables. La siguiente sentencia define a arch como un puntero a archivo .
FILE *arch;

Archivos

Apertura De Un Archivo
Para abrir un archivo se utiliza la funcin fopen() (f: file, archivo en ingls;
open: abrir). Esta funcin sirve para asociar la variable puntero a archivo, que
llamaremos archivo lgico, con un archivo en disco u otro medio externo, que
llamaremos archivo fsico. Adems informa el tipo de archivo y el modo de
apertura. El prototipo de fopen() es:
FILE *fopen(char nombrearchivo[], char modo[]);
donde nombrearchivo[] es una cadena de caracteres, constante o variable, que
formen un nombre archivo vlido para el sistema operativo, y puede incluir la
especificacin de una va de acceso y modo es una cadena que indica el tipo de
archivo (de texto o binario) y si el archivo se va a usar slo de lectura, slo de
escritura o para ambas cosas. El valor de retorno de fopen() es un puntero a
archivo. Si tiene lugar un error cuando se intenta abrir el archivo, fopen() retorna
el valor NULL (un puntero nulo).
Si quisiramos leer desde un archivo de nombre mensaje.txt localizado en
el mismo directorio que el programa, escribimos:
arch = fopen(mensaje.dat, rt);
donde rt indica que mensaje.txt se va abrir como un archivo de texto slo de
lectura (r: reading, lectura en ingls y t:text).
Si queremos asociar a la variable puntero a archivo fp a un archivo de
nombre ventas.dat que est en el directorio prueba de un disco flexible,
escribimos:
fp = fopen(A:\prueba\ventas.dat, rt);
El siguiente programa define, en primer lugar, una variable puntero a archivo
de nombre p y luego asocia este puntero con un archivo de texto de nombre
prueba.txt. Si el archivo no existe ocurrir un error y fopen() retorna NULL.
#include <stdio.h>
#include <conio.h>
main()
{ FILE *p;
p = fopen("prueba.txt","rt");
if (p == NULL)
printf("El archivo no existe");
else
printf("El archivo existe");
}
4

Archivos

Si el valor de modo es wt, fopen() crea un archivo de texto para escritura


(w: writing, escritura en ingls). En este caso ocurre un error si el disco est lleno
o protegido contra escritua. La siguiente sentencia crea un archivo de nombre
info.txt y lo asocia a la variable arch.
arch = fopen(info.txt, wt);
Cuando se abre un archivo para escribir pueden ocurrir dos cosas:
Si el archivo no existe entonces fopen() lo crea.
Si el archivo existe entonces fopen() lo borra y crea uno nuevo.
Ejercicios
Escribir un programa para crear un archivo de nombre comison.dat. Ejecutar el
programa y verificar si el archivo ha sido creado. Cuntos bytes tiene?
Verificar si un archivo existe, sino crearlo. Emitir mensajes aclaratorios.
Escritura De Un Carcter
La funcin fputc() (f: file; put: poner; c: carcter) se uitliza para escribir
caracteres en un archivo que haya sido abierto anteriormente para escribir
mediante la funcin fopen(). El prototipo es:
int fputc(int car, FILE *arch);
donde car es el carcter que se quiere escribir y arch es una variable puntero a
archivo.
Por razones histricas se llama formalmente int al car, pero slo se utiliza el
byte menos signifactivo.
Cierre De Un Archivo
La funcin fclose() (f: file; close: cerrar) se emplea para cerrar toda
vinculacin entre la variable de tipo archivo y el archivo propiamente dicho.
Escribe todos los datos que pudieran quedar en la memoria intermedia de disco en
el archivo (buffers) y hace un cierre formal a nivel de sistema operativo en ese
archivo. No cerrar un archivo es arriesgarse a problemas de todo tipo, entre los que
se pueden incluir la prdida de datos y archivos destruidos. Por otro lado ya debe
resultar conocido el hecho de que el sistema operativo limita el nmero de
archivos que pueden estar abiertos al mismo tiempo, as que quiz resulte
necesario cerrar un archivo antes de abrir otro. Su prototipo es:
5

Archivos

int fclose(FILE *arch);


Si fclose() retorna un valor cero indicar que la operacin de cierre ha tenido
xito; cualquier otro valor indica un error.
El siguiente programa crea un archivo y escribe en l una cadena que se
ingresa por teclado.
#include <stdio.h>
#include <conio.h>
#include <string.h>
main()
{ FILE * f;
int i;
char mensaje[80];
f = fopen("mensaje.txt","wt");
clrscr();
printf("Ingresar un mensaje: ");
gets(mensaje);
i = 0;
while (mensaje[i])
{ fputc(mensaje[i],f);
i++;
}
fclose(f);
}
Ejercicios
Editar una programa que escriba Hola Mundo en un archivo. Luego abra el
archivo con un editor de texto para verificar que el programa ejecut
correctamente.
Escribir un prorama que solicite al usuario el nombre de un archivo. Luego el
programa debe leer caracteres por teclado y escribirlos en el archivo hasta que se
pulse el signo $.
Lectura De Un Carcter Y La Funcion eof()
La funcin fgetc() (get: obtiene; c: carcter) se emplea para leer caracteres
desde un archivo que haya sido abierto anteriormente para lectura mediante la
funcin fopen(). El prototipo es:

Archivos

int fgetc(FILE *arch);


donde arch es una variable puntero a archivo.
La funcin fgetc() proporciona una marca de EOF (end of file: fin de
archivo) cuando se haya alcanzado el fin del archivo. Tambin puede usarse la
funcin de biblioteca feof() para detectar el fin del archivo. Esta funcin
proporciona el valor 1 (verdadero) si se ha alcanzado el fin del archivo; en caso
contrario, devuelve el valor cero. El prototipo de feof() es:
int feof(FILE *arch);
El siguiente progrma lee caracteres desde un archvo y los muestra por
pantalla
#include <stdio.h>
#include <conio.h>
#include <string.h>
main()
{ FILE * f;
char car;
f = fopen("mensaje.txt","rt");
clrscr();
while(!feof(f))
{ car = fgetc(f);
printf("%c", car);
}
getch();
fclose(f);
}
Lectura Y Escritura De Cadenas
En lugar de leer o escribir carcter por carcter, podemos leer o escribir
cadenas de caracteres. Las funciones fgets() y fputs() hacen esas opearaciones.Los
prototipos son:
char *fgtes(char cad[], int longitud, FILE *arch);
char *fputs(char cad[], FILE *arch);
La funcin fgets() lee una cadena del archivo asociado a arch hasta que o
bien se lee un carcter nuevalnea o bien se han ledo longitud-1 caracteres. La
funcin fputs() escribe la cadena cad en el archivo que est asociado a arch.
7

Archivos

Una Aplicacin De Archivos De Texto


Vamos a escribir un programa para encriptar y desencriptar un archivo de
texto. Usaremos un algoritmo muy simple que ya lo usaba Julio Cesar hace 2000
aos. Para encriptar el usuario elige un nmero entre 1 y 25 que indica el
corrimiento a ser aplicado a cada letra del texto. Por ejemplo, si el nmero es 3,
reemplazaremos la A por D, la B por E y as se sigue como se ve en el siguiente
dibujo:
A B C D E F G H I J K L M N O P Q R S T U W X Y Z

D E F G H HI J K L M N O P Q R S T U W X Y Z A B C
Las letras minsculas las transforamemos a maysculas y odos los caracteres que
no son letras no se corren.
Hacerlo
Ejercicio
Escribir un programa para descriptar un archivo que ha sido encriptado con el
programa anterior.
Un Archivo Como Secuencia De Bytes
Supongamos que quisiramos construir un archivo con nombres y
direcciones. El siguiente programa recibe nombres y direcciones del teclado, y los
transcribe como una secuencia de caracteres a un archivo.
#include <stdio.h>
#include <conio.h>
#include <string.h>
void leerapellido (char a[]);
void leerdatos(char n[], char c[], char l[], char p[], char cp[]);
void grabar(char a[], char n[], char c[], char l[], char p[], char
cp[], FILE *s);
main()
{ FILE * salida;
int i;
char apellido[10], nombre[10], calleynro[20];
char localidad[10], provincia[15], codpostal[5];
salida = fopen("datos.txt","wt");
leerapellido (apellido);
while (strlen(apellido) > 0)
{
leerdatos(nombre, calleynro, localidad, provincia,
codpostal);

Archivos

grabar(apellido, nombre, calleynro, localidad, provincia,


codpostal, salida);
leerapellido(apellido);
}
fclose(salida);
}
void leerapellido (char a[])
{ clrscr();
printf("Apellido: ");
gotoxy(16,1);
gets(a);
}
void leerdatos(char n[], char c[], char l[], char p[], char cp[])
{
printf("\nNombre: ");
printf("\n\nCalle y Nro.: ");
printf("\n\nLocalidad: ");
printf("\n\nProvincia: ");
printf("\n\nCodigo Postal: ");
gotoxy(16, 3);
gets(n);
gotoxy(16,5);
gets(c);
gotoxy(16,7);
gets(l);
gotoxy(16,9);
gets(p);
gotoxy(16,11);
gets(cp);
}
void grabar(char a[],char n[], char c[], char l[], char p[], char
cp[], FILE *s)
{ fputs(a, s);
fputs(n, s);
fputs(c, s);
fputs(l, s);
fputs(p, s);
fputs(cp, s);
}

Si se usan los siguientes nombre y direcciones como entrada,


Sanchez Juan
Sarmiento 1234
Olivos
Buenos Aires
1636

Martinez Oscar
Italia 2345
Florida
Buenos Aires
1635

Archivos

Cuando se lista el archico datos.txt en la pantalla, se ve lo siguiente:


SanchezJuanSarmiento 1234OlivosBuenos Aires1636MartinezOscarItalia
2345FloridaBuenos Aires1635

El programa transcribe la informacin al archivo tal como se especific:


como una secuencia de bytes que no contiene informacin adicional. No sabemos
donde termina el primer apellido o donde comienza los datos de la segunda
persona. Una vez que se pone toda la informacin junta como una secuencia de
bytes, no hay forma de separarla de nuevo.
Lo que sucede es que se ha perdido la integridad de las unidades
organizacionales fundamentales de los datos de entrada; estas unidades
fundamentales no son los caracteres individuales, sino los agregados significativos
de caracteres, tales como Sanchez o Italia 2345. Cuando se trabaja con
archivos, se denomina campos a esos agregados fundamentales. Un campo es la
unidad de informacin lgicamente significativa ms pequea de un archivo.
Un campo es una idea lgica, una herramienta conceptual. Un campo no
necesariamente existe en algn sentido fsico, pero aun as es importante para la
estructura del archivo. Cuando la informacin sobre el nombre y la direccin se
transcribe como una secuencia de bytes no diferenciables, se pierde el rastro de los
campos que le dan significado a la informacin. Es necesario organizar el archivo
de manera que la informacin se mantenga dividida en campos.
Los siete primeros campos del ejemplo constituyen un conjunto asociado
con alguien llamado Juan Sanchez y los siguinetes siete son un conjunto asociado
con Oscar Martinez, A estos conjuntos de campos se les llama registros.
Al igual que la nocin de campo, un registro es otra herramienta conceptual.
Es otro nivel de organizacin que se impone sobre los datos para preservar su
significado. Los registros no existen en el archivo en un sentido fsico sino que
constituyen una nocin lgica.

10

Archivos

Hay varios mtodos para organizar un archivo en registros y, a su vez, stos


en campos. Uno de estos mtodos es hacer tanto a los campos como a los registros
de longitud fija.
Un archivo organizado en registros puede ser de texto o binario, pero en
general se prefieren los archivos binarios. Esto es as porque el procesamiento de
los archivos de texto es mucho ms lento que los binarios.
Representacin De Un Archivo De Registros
Supongamos que una empresa tiene la siguiente informacin sobre sus
empleados: edad, sexo, departamento y categora. La informacin de todos los
empleados constituyen el archivo; la informacin relativa a cada empleado es un
registro y finalmente edad, sexo, departemaento y catagoria son los campos que
forman un registro.
El siguiente esquema representa este archivo. La primer fila contiene los
nombres de los campos, la primer columna el nmero de registro y con /*
indicamos el fin del archivo.
EDA
D

registro
0
registro
1
registro
2

SEX
O

DEPARTEMENTO CATEGORA

30

25

40

/*
Este esquema es slo una representacin lgica del archivo. El archivo es
simplemente una secuencia de bytes. Fsicamente este archivo es:
000000000001110100011000000000000001100100001........
Los primeros 16 bits representan al nmero 30, los siguiente 8 a la letra A,
los prximos 16 al nmero 6, a as sucesivamente.

11

Archivos

Operaciones Con Archivos De Registros


As como los archivos de texto son similares a una pgina escrita, el
concepto de archivo de registros en informtica no difiere del concepto que se
tiene fuera de ella. Supongamos que la ctedra de Programacin tiene un fichero
para cada comisin a su cargo. Por cada alumno se tiene una tarjeta con la
informacin del mismo. Todas las tarjetas tienen la misma estructura y en cada
fichero hay tantas tarjetas como alumnos haya en la comisin. Supongamos que la
estructura de la tarjeta es: matrcula del alumno, nombre, calificacin del primer
examen parcial, calificacin del segundo examen parcial y nota de concepto.

Archivo Comisin 1

Archivo Comisin 2

Formato de cada tarjeta


Qu operaciones se realizan con las tarjetas de un archivo? En primer lugar
debemos crear el fichero: esto es disear el formato de cada tarjeta y asignarles un
lugar (una caja rectangular). Luego debemos escribir la informacin de cada
alumno: matricula y apellido y nombre (al inicio del ao lectivo no se tienen las
calificaciones). Una vez evaluado el primer examen debemos modificar cada
tarjeta agregando la calificacin correspondiente. Supongamos que al mes de
iniciado el curso, ingresa un nuevo alumno, en tal caso debemos confeccionar la
tarjeta correspondiente y agregarla al fichero. A los dos meses un alumno
abandona el curso, entonces procedemos a eliminar la tarjeta del fichero o bien
agregarle una marca para indicar que ese alumno ya no concurre a clase. En la
mitad del curso debemos obtener un listado para presentar al Decano, entonces
12

Archivos

debemos recorrer el archivo, tarjeta por tarjeta, y volcar la informacin en una


hoja de papel. En cualquier momento un alumno puede preguntar por su situacin,
entonces debemos buscar la tarjeta correspondiente e informarle. Al final del curso
debemos presentar un listado que contenga a las dos comisiones juntas ordenadas
por apellido: en este caso debemos fusionar o intercalar los dos archivos,
ordenarlo por apellido y luego revisar tarjeta por tarjeta para volcar en papel la
informacin solicitada. Estas son algunas de las operaciones que pueden
presentarse.
Las mismas operaciones se realizan con archivos de disco. Estas
bsicamente son:
1.
2.

3.
4.
5.
6.

Creacin
Actualizacin, incluyendo
insercin de registros
modificacin de uno o ms campos
eliminacin de registros
Recuperacin, incluyendo
consulta
generacin de reportes
Ordenacin
Fusin
Mantenimiento
estructuracin
compactacin

Creacin De Un Archivo
La creacin de un archivo consiste en la asignacin de un lugar en el disco y
eventualmente en la carga de la informacin. La carga de la informacin puede
hacerse interactivamente o bien desde otro archivo.
Actualizacin De Un Archivo
Consiste en la insercin de nuevos registros o en la eliminacin de registros
que no se utilizan ms. Tambin puede ocurrir que debamos modificar uno o ms
datos del registro.
Recuperacin De La Informacin
Existen bsicamente dos clases de recuperacin de la informacin: consulta
y generacin de reportes. La consulta, generalmente, produce poca informacin y
es interactiva, por ejemplo el alumno Gonzlez pregunta qu nota obtuvo en el
primer examen. En cambio, el reporte puede generar muchas pginas de salida de
informacin como obtener un listado de todos los alumnos que no han aprobado el
segundo examen.

13

Archivos

Ordenacin
Generalmente los archivos se crean con algn criterio de ordenacin, en el
ejemplo que estamos tratando puede ser la matrcula, pero en cualquier momento
podemos necesitar el archivo ordenado por algn otro campo. Ac, como veremos
ms adelante, debemos considerar el caso de archivos chicos y archivos grandes.
Fusin
La fusin o intercalacin de archivos es otra tarea frecuente en los sistemas
de procesamiento de datos. Supongamos un banco que decide cerrar una de sus
sucursales, entonces todos los clientes de sta debern pasar a otra sucursal y por
lo tanto los archivos de ambas sucursales debern fusionarse.
Mantenimiento De Archivos
Cambios hechos sobre archivos para mejorar la eficiencia de los programas
que los utilizan son conocidos como actividades de mantenimiento. Dentro de este
tipo de operaciones debemos considerar la modificacin de la estructura de los
registros y la compactacin. Supongamos que para cada alumnos deseamos
agregar una tercer nota, deberemos entonces recorrer todo el archivo modificando
la estructura de cada registro. La compactacin consiste en eliminar fsicamente
aquellos registros que han sido dados de baja. Generalmente cuando se elimina un
registro en realidad se lo marca como anulado. Si hay muchas bajas y no se realiza
compactacin el archivo tendr un porcentaje elevado de registros que se
encuentran en desuso.

Funciones Relacionadas Con Archivos Binarios


Para abrir un archivo binario se utiliza la misma funcin fopen(), donde
algunos de los valores para modo pueden ser:
rb
Abrir un archivo binario para lectura.
wb Crear un archivo binario para escribir.
r+b Abrir un archivo binario para lectura/escritura.
Las funciones para cerrar un archivo y para detectar el fin del mismo son las
mismas que para archivos de texto. Finalmente para transferir informacin de la
memoria RAM a un archivo se utiliza la funcin fwrite() (f: file, write: escribir) y,
para transferir informacin de un archivo a la memoria RAM se usa fread(), (f:
file; read: leer). En realidad estas dos funciones se pueden utilizar tanto con
archivos de texto o con binarios, pero para los primeros es preferible usar fgetc(),
fputc(), fgets() o fputs().

14

Archivos

La Funcin fwrite()
El prototipo de fwrite() es:
unsigned fwrite(void *p, int cant_bytes, int contador, FILE *arch);
donde p es un puntero a void, cant_bytes y contador son enteros y arch es un
puntero a archivo. La funcin fwrite() transfiere contador*cant_bytes bytes desde
la direccin de memoria indicada por p al archivo asociado a arch.
El siguiente programa guarda el nmero 5 en el archivo binario numero.dat.
#include <stdio.h>
#include <conio.h>
main()
{ FILE * salida;
int i;
salida = fopen("numero.dat","wb");
i = 5;
fwrite(&i, 2, 1, salida);
fclose(salida);
}
La sentencia:
fwrite(&i, 2, 1, salida);
transfiere dos bytes (tamao de un entero) desde la direccin de memoria &i al
archivo lgico salida.
A continuacin se muestra otro ejemplo con fwrite().
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void generar_aleat(float a[], int n);
main()
{ FILE * f;
float a[10];
f = fopen("aleatorios","wb");
generar_aleat(a, 10);
fwrite(a, 4, 10, f);
fclose(f);

15

Archivos

}
void generar_aleat(float a[], int n)
{ int i;
randomize();
for (i = 0; i < n; i++)
a[i] = random(1000);
}

La sentencia:
fwrite(a, 4, 10, f);
transfiere 40 bytes desde la variable a al archivo asociado con f. Notar que en el
primer ejemplo usamos &i y en el segundo simplemente a por qu?.
C proporciona la funcin sizeof() que es muy til pues nos evita recordar el
tamao de los enteros, float, double, etc. Para invocarla, escibimos:
sizeof(tipo_de_datos);
donde tipo_de_datos es cualquier tipo permitido, incluso un tipo struct, y el
valor de retorno es la cantidad de bytes que ocupa ese tipo.
Valor de retorno
sizeof(int);

sizeof(double);

struct emp
{ int edad;
char sexo;
int depto;
char categoria;
};

sizeof(emp);
En el siguiente ejemplo vamos a crear un archivo y alamacenar en l, el
nmero de matrcula, el apellido y nombre y la calificacin del primer examen de
los alumnos correspondientees a una comisin. Prever que otros programas puedan
ingresar las calificaciones de otros dos examenes; dar de baja a registros que
16

Archivos

corresponden a alumnos que han abandonado el curso o bien dar de alta a nuevos
alumnos.
En primer lugar debemos definir la estrucutura reg como sigue:
struct reg
{ char matricula[5];
char apel_nom[30];
int calif_1;
int calif_2;
int calif_3;
char borrado;
};

El campo borrado tendr el valor N para los alumnos activos y el valor S


para alumnos que han sido de baja. El siguiente programa crea un archivo llamado
comis_1, lee la informacin desde el teclado y la almacena en el archivo.
#include
#include
#include
#include
#include

<stdio.h>
<conio.h>
<string.h>
<entrada.h>
<stdlib.h>

FILE *abrir();
void altas (FILE * arch);
int valido1(char c);
struct reg
{ char matricula[5];
char apel_nom[30];
int calif_1;
int calif_2;
int calif_3;
char borrado;
};
main()
{ FILE * arch;
arch = abrir();
altas(arch);
fclose(arch);
}
void altas (FILE * arch)
{ struct reg alumno;
char nota[3];
clrscr();
printf("Matricula: ");
gotoxy(20,1);
getstr(alumno.matricula, 4, 4, valido1);
while (strcmp(alumno.matricula, "0000") != 0)

17

Archivos

gotoxy(1,3);
printf("Apellido y Nombre: ");
gotoxy(1,5);
printf("Calificacion 1: ");
gotoxy(20, 3);
gets(alumno.apel_nom);
gotoxy(20,5);
getstr(nota, 1, 2, valido1);
alumno.calif_1 = atoi(nota);
alumno.borrado = N;
fwrite(&alumno,sizeof(struct reg),1,arch);
clrscr();
printf("Matricula: ");
gotoxy(20,1);
getstr(alumno.matricula, 4, 4, valido1);
}

int valido1(char c)
{
return ( c >= '0') && (c <= '9');
}
FILE *abrir()
{ FILE *pf;
char nom_arch[15];
clrscr();
printf("Ingresar nombre del archivo: ");
gets(nom_arch);
pf = fopen(nom_arch,"r+b");
if (pf == NULL)
pf = fopen(nom_arch,"wb");
return pf;
}

Haremos el seguimiento de este algoritmo. Al declarar las variables arch,


reg y nom_arch, quedan definidas tres variables en la memoria RAM de la
siguiente manera:
Memoria RAM
arch

alumno
matricula

nom_arch
apel_nom

calif_1

calif_2

calif_3

borrado

En primer lugar se solicita al usuario que ingrese un nombre de archivo el


que se guarda en la variable nom_arch. Supongamos que el usuario escriba
comis_1, entonces la memoria tendr el siguiente aspecto.
Memoria RAM

18

Archivos

arch

alumno
matricula

nom_arch
comis_1
apel_nom

calif_1

calif_2

calif_3

borrado

Al ejecutarse arch = fopen(nom_arch,wb), se crea un archivo en disco


llamado comis_1 y la variable arch apunta al mismo.
Memoria RAM
arch

alumno
matricula

nom_arch
comis_1
apel_nom

calif_1

calif_2

calif_3

borrado

Disco
comis_1 (0 bytes)

Luego el programa solicita al usuario que ingrese un nmero de matrcula


que almacena en el campo matricula de la variable alumno. Supongamos que
ingresa 7856.
Memoria RAM
arch

alumno
7856

nom_arch

comis_1

matricula apel_nom

calif_1

calif_2

calif_3

borrado

Disco
comis_1 (0 bytes)

Como este valor es distinto de 0000 comienza a ejecutarse el ciclo while


en el cual se solicita el nombre y apellido del alumno y la calificacin del primer
examen. Supongamos que el usuario ingresa Gonzlez Alberto y como
calificacin un 5. Observar que el algoritmo asigna N a alumno.borrrado.
Memoria RAM
arch

alumno
7856

nom_arch

Gonzlez Alberto

matricula apel_nom

5
calif_1

19

N
calif_2

calif_3

borrado

comis_1

Archivos

Disco
comis_1 (0 bytes)

Luego se ejecuta la accin fwrite(&alumno, sizeof(reg), 1, arch);, la


informacin que est en la variable alumno se transfiere al archivo comis_1,
quedando:
Memoria RAM
arch

alumno
7856

Gonzlez Alberto

matricula apel_nom

calif_1

N
calif_2

concepto

nom_arch
comis_1

borrado

Disco
comis_1
7856 Gonzlez Alberto

La funcin fwrite() adems de transferir la informacin de la memoria al


archivo de disco hace avanzar el puntero de archivo tantos bytes como tenga el
registro.
El programa continua solicitando otro nmero de matrcula, que se lee en
alumno.matricula, reemplazando el valor ledo al que estaba antes. Por ejemplo,
Memoria RAM
arch

alumno
7860

Gonzlez Alberto

matricula apel_nom

calif_1

N
calif_2

concepto

nom_arch
comis_1

borrado

Disco
comis_1
7856 Gonzlez Alberto 5

Como el valor ledo es diferente de cero se ejecuta el ciclo while que solicita
un nuevo nombre y otra calificacin que se leee en alumno.nombre y en
alumno.calif_1 respectivamente y se asigna N a alumno.borrado.
Memoria RAM

20

Archivos

arch

alumno
7860

Martinez Jorge

matricula apel_nom

nom_arch
comis_1

calif_1

calif_2

concepto

borrado

Disco
comis_1
7856 Gonzlez Alberto

Se ejecuta nuevamente la fwrite(), quedando,


Memoria RAM
arch

alumno
7860

Martinez Jorge

matricula apel_nom

nom_arch
comis_1

calif_1

calif_2

concepto

borrado

Disco
comis_1
7856 Gonzlez Alberto

7860 Martnez Jorge 8

As sigue el algoritmo hasta que se ingresa desde el teclado el valor de


matricula igual a 0000, con lo cual termina el ciclo while y se cierra el archivo.

Ejercicios
Ejercicio 14.#
Escribir un pogrma para construir un archivo de 10 nmeros enteros que se
ingresan por teclado.
Escribir funciones para:
a. crear un archivo de Clientes, donde cada cliente consta de la siguiente
informacin: nombre, calle, nmero, localidad y provincia, cuit, saldo.
b. cargar datos en el archivo anterior.
Crear y cargar datos en un archivo de alumnos, cada registro debe contener la
siguiente informacin: nombre, direccin, edad y fecha.

21

Archivos

La Funcin fread()
Un archivo binario no puede ser visualizado con un editor de texto. Por
ejemplo, el si abrimos el archivo aleatorios, construido anterioemente, con
NOTEPAD o cualquier otro editor veriamos algo similar alo siguiente:
2222C22C228D2222YD2222C22D2222C22@ D2222C22sD

Para leer un archivo binario debemos usar fread(). El prototipo de esta


funcin es:
unsigned fread(void *p, int cant_bytes, int contador, FILE *arch);
donde p es un puntero a void, cant_bytes y contador son enteros y arch es un
puntero a archivo. La funcin fread() transfiere contador*cant_bytes bytes desde
el archivo asociado a arch a la direccin de memoria indicada en p.
Para leer un archivo existente debemos abrirlo en modo lectura o
lectura/escritura. La ejecucin de esta funcin asegura la localizacin del archivo
en el soporte externo y el posicionamiento del apuntador al principio del archivo
inmediatamente antes del primer registro del archivo. Cada ejecucin de fread()
lee contador*cant_bytes en la direccion indicada en p y desplaza el apuntador del
archivo para dejarlo inmediatamente antes de los prximos bytes a leer. La funcin
feof(arch) es evaluada automticamente cada vez que se realiza una operacin de
lectura y tiene el valor falso mientras el apuntador no haya pasado la marca de fin
de archivo. Toma el valor cierto en el momento en que la ejecucin de fread()
encuentre la marca fin de archivo.
Los programas siguientes leen y muestran por pantalla los archivos
numero.dat y aleatorios construidos anteriormente.
#include <stdio.h>
#include <conio.h>
main()
{ FILE * salida;
int i;
salida = fopen("numero.dat","rb");
fread(&i, 2, 1, salida);
printf("%d", i);
getch();
fclose(salida);
}

#include <stdio.h>
#include <conio.h>
main()
{ FILE * aleat;

22

Archivos

float a[10];
int i;
aleat = fopen("aleatorios","rb");
fread(a, 4, 10, aleat);
fclose(aleat);
clrscr();
for (i = 0; i < 10; i++)
printf("\n%7.2f",a[i]);
getch();
}

La siguiente funcin nos permite visualizar el archivo comis_1.


void mostrar (FILE * arch)
{ struct reg alumno;
int linea=3;
clrscr();
printf("Matricula
Apellido y Nombre
Calificacion
1");
fread(&alumno, sizeof(reg), 1, arch);
while (! feof(arch))
{ gotoxy(1,linea);
printf("%s", alumno.matricula);
gotoxy(20,linea);
printf("%s", alumno.apel_nom);
gotoxy(50,linea);
printf("%d", alumno.calif_1);
linea++;
fread(&alumno, sizeof(reg), 1, arch);
}
printf("\n\nOprimir una tecla para continuar..." );
getch();
}

La siguiente figura muestra la evolucion del valor de arch y de la funcin feof() a


medida que se ejecuta este programa..
Despus de la apertura del archivo,
Disco
comis_1

R1

R2

arch

R3

valor de eof(arch)

23

Rn

/*

Archivos

Despus de la primera ejecucin de fread(),


R1

R2

arch

R3

Rn

/*

Rn

/*

Rn

/*

valor de eof(arch)

Despus de la n-sima ejecucin de fread(),


R1

R2

arch

R3

valor de eof(arch)

Despus de la (n+1)-sima ejecucin de fread(),


R1

R2

arch

R3

valor de eof(arch)

La ejecucuin del programa anterior muestra una salida por pantalla similar a:
Matricula
7896
7860
6560
7890
8990
7555

Apellido y Nombre
Gonzalez Alberto
Martinez Jorge
Smith Roberto
Silveira Sebastian
Rizzo Juan
Rodriguez Pedro

Oprimir una tecla para continuar...

24

Calificacion 1
5
8
6
3
2
5

Archivos

Ejercicios
Escribir un algoritmo que busque en el archivo de enteros construido en el ejercicio
14#, el entero ms pequeo y ms grande del archivo.
visualizar el archivo construido en ejercicio 14.#
Visualizar el archivo creado en 14#

La Funcin fseek()
En este ltimo ejemplo hemos procesado al archivo secuencialmente; lemos
el primer registro y mostramos alunos campos por pantalla, luego lemos el
segundo registro y as sucesivamente hasta encontrar el fin del archivo. Sin
embargo en muchas aplicaciones es necesario acceder a la informacin de un
determinado registro. La funcin fseek() nos permite acceder directamente a
cualquier posicin del archivo, sin necesidad de leer toda la informacin anterior.
Su prototipo es:
int fseek(FILE *arch, long num_bytes, int origen);
Donde arch es un puntero a archivo, num_bytes es un entero largo y origen es un
entero cuyos valores pueden ser 0, 1 2. El valor de num_bytes es la cantidad de
bytes a partir de origen que debe tomarse como la nueva posicin actual. Los
valores de origen tiene el siguiente significado.
0:
1:
2:

Principio del archivo


Posicin actual
Fin de archivo

El siguiente programa muestra el cuarto nmero del archivo aleatorios.


#include <stdio.h>
#include <conio.h>
main()
{ FILE * aleat;
float b;
aleat = fopen("aleatorios","rb");
clrscr();
fseek(aleat, 12, 0);
fread(&b, 4, 1, aleat);
printf("\n%7.2f",b);
getch();
25

Archivos

fclose(aleat);
}

Algoritmos Para La Recuperacin De La Informacin


En este grupo de algoritmos se encuentra la consulta, generalmente
interactiva, y el informe o reporte, generalmente salida impresa, aunque tambin
puede ser por pantalla o incluso a archivo de disco.
Informe
Un informe simple se refiere a mostrar los campos de todos los registros o
slo algunos campos o bien algunos o todos los campos de los registros que
cumplen alguna condicin. Un ejemplo de informe es la funcin mostrar()
desarrollada en la seccin anterior. Otro ejemo de informe es els siguiente:
Obtener un listado de los alumnos inscriptos en la comisin 1 que no
aprobaron el primer examen, mostrando al final del mismo la cantidad total de
alumnos inscriptos y la cantidad y porcentaje de insuficientes.
Para obtener este informe debemos recorrer el archivo desde el primer
registro hasta encontrar el fin del archivo y por cada uno debemos consultar por la
calificacin del primer examen e imprimir la matrcula y el nombre de aquellos
que han obtenido una calificacin menor a 4. Adems debemos llevar un contador
para los alumnos inscriptos y otro para los que no aprobaron.
void informe (FILE * arch)
{ struct reg alumno;
int linea=3;
int inscr, insuf;
clrscr();
printf("Matricula
Apellido y Nombre");
inscr = 0;
insuf = 0;
fseek(arch,0,0); /* arch apunta al inicio del archivo*/
fread(&alumno, sizeof(reg), 1, arch);
while (!feof(arch))
{
if (alumno.borrado == 'N')
{ inscr++;
if (alumno.calif_1 < 4)
{
insuf++;
gotoxy(1,linea);
printf("%s", alumno.matricula);
gotoxy(20,linea);
printf("%s", alumno.apel_nom);
linea++;
}
}
fread(&alumno, sizeof(reg), 1, arch);
}
printf("\n\nTotal de inscriptos: %d", inscr);

26

Archivos

printf("\nTotal de insuficientes: %d", insuf);


printf("\nPorcentaje de insuficientes: %5.2f",
100.0*insuf/inscr);
printf("\n\nOprimir una tecla para continuar..." );
getch();
}

El imforme que se obtiene es similar al siguiente:


Matricula
7890
8990

Apellido y Nombre
Silveira Sebastian
Rizzo Juan

Total de inscriptos: 6
Total de insuficientes: 2
Porcentaje de insuficientes: 33.33
Oprimir una tecla para continuar...

Todos los algoritmos para recorrer un archivo constan de los siguientes


pasos: colocar la variable puntero de archivo al inicio de ste, leer el primer
registro, mientras no sea el fin del archivo procesar el registro recin ledo y leer el
prximo registro, repetir estos dos ltimos pasos hasta llegar la final del archivo.
Cuando ste se ha alcanzado, generalmente, hay que ejecutar un proceso final.

Consulta de un registro
Supongamos que deseamos consultar la informacin de un alumno
conociendo su matrcula. Como el archivo no est ordenado debemos realizar una
bsqueda secuencial, similar a la que realizbamos cuando la informacin est
almacenada en arreglos. Posicionar al puntero de archivo al incio del mismo;
acceder al primer registro, si el campo matrcula es igual a la matrcula dada
mostramos la informacin, sino accedemos al segundo registro; se contina as
hasta que se encuentre la matrcula o se haya accedido al final del archivo. La
funcin buscar() busca la matricula en el archivo, si la encuentra retorna el
nmero de registro correspondiente y si no la encuentra retorna -1.
void consulta (FILE * arch)
{ struct reg alumno;
char mat_a_buscar[5];
int k;
clrscr();

27

Archivos

printf("Ingresar matricula: ");


getstr(mat_a_buscar, 4,4, valido1);
while (strcmp(mat_a_buscar,"0000") != 0)
{
k = buscar(mat_a_buscar, arch);
if ( k != -1)
{
fseek(arch, k*sizeof(reg), 0);
fread(&alumno, sizeof(reg), 1 ,arch);
if (alumno.borrado == 'N')
{
printf("\nApellido y Nombre: %s", alumno.apel_nom);
printf("\n\nCalificacion 1: %d", alumno.calif_1);
printf("\n\nCalificacion 2: %d", alumno.calif_2);
printf("\n\nCalificacion 3: %d", alumno.calif_3);
printf("\n\nOprima una tecla para continuar...");
getch();
}
else
{
printf("\n\nLa matricula no se encontro");
getch();
}
}
else
{
printf("\n\nLa matricula no se encontro");
getch();
}
clrscr();
printf("Ingresar matricula: ");
getstr(mat_a_buscar, 4,4, valido1);

}
}

int buscar (char mat[], FILE * arch)


{
struct reg alumno;
int i;
i = 0;
fseek(arch, 0, 0);
fread(&alumno, sizeof(reg), 1, arch);
while (!feof(arch))
{ if (strcmp(mat,alumno.matricula) == 0)
return i;
fread(&alumno, sizeof(reg), 1, arch);
i++;
}
return -1;
}

La funcin consulta() muestra una pantalla como la siguiente:


Ingresar matricula: 7896
Apellido y Nombre: Fernandez Sebastian

28

Archivos

Calificacion 1: 8
Calificacion 2: -4865
Calificacion 3: -18945
Oprima una tecla para continuar...

Los valores absurdos de la segunda y tercera calificacin se deen a que a los


campos alumno.calif_2 y alumnos.calif_3 no se le han asignado ningn valor. Es
conveniente que en la funcion alta() a aquellos campos que no tienen valores, se
les asigne el valor nulo del tipo de dato correspondiente.

Ejercicios
Utilizando el archivo creado en 14#
c. consultar un cliente.
b. Construir funciones que permitan responder a las siguientes preguntas:
a. Cuales clientes tienen saldo inferior a 0?
b. Cuantos clientes viven en la provincia de Crdoba?
c. Listar los clientes cuyo nombre comienza con 'M'?
d. Cual es el cliente con saldo mayor?
A pertir del archivo de alumnos creado en ejercicio 14#, escibir funciones para:
construir un nuevo archivo que contenga slo los nombres y edad
obtener un listado con el nombre y direccin de cada alumno cuyos nombres
comiencen con las letras A, B o C y hayan nacido en el mes de mayo.
Algoritmos Para Actualizar Archivos
Las tres operaciones de actalizacin de archivos son:
altas: ingreso de nuevos registros
bajas: eliminacin de registros que no se necesitan ms
modificacin: modificar la informacin de uno o ms campos uno ms
registros

29

Archivos

Altas
Como hemos dicho al principio del captulo siempre es conveniente que
haya un dato, que se denomuina clave, que identifique en forma biunvoca al
registro. En el ejemplo que estmos tratando este dato pueder ser la matrcula, ya
que no hay dos alumnos con la misma matrcula.
Para realizar un alta posteriormente a haber creado el archivo e ingresado
algunos datos, debemos:
solcitar la clave (en este ejemplo la matrcula);
buscar la matricula en el archivo;
si la matrcula ya existe;
emitir un mensaje de error;
sino
solictar los datos al usuario;
grabarlos en el archivo;
La funcin altas() descripta anteriormente permite el ingreso de datos en un
archivo vaco. A continuacin la funcin que se describe puede usarse si el archivo
est vaco o si ya contiene algunos datos.
void altas (FILE * arch)
{ struct reg alumno;
char nota[3];
int k;
clrscr();
printf("Ingresar matricula: ");
getstr(alumno.matricula, 4,4, valido1);
while (strcmp(alumno.matricula,"0000") != 0)
{
k = buscar(alumno.matricula, arch);
if ( k == -1)
{

gotoxy(1,3);
printf("Apellido y Nombre: ");
gotoxy(1,5);
printf("Calificacion 1: ");
gotoxy(20, 3);
gets(alumno.apel_nom);
gotoxy(20,5);
getstr(nota, 1, 2, valido1);
alumno.calif_1 = atoi(nota);
alumno.borrado = 'N';
fseek(arch,0,2);
fwrite(&alumno,sizeof(struct reg),1,arch);

}
else
{ printf("\n\nLa matricula ya existe");
getch();

30

Archivos

}
clrscr();
printf("Ingresar matricula: ");
getstr(alumno.matricula, 4,4, valido1);

Bajas
Otra de las operaciones frecuentes en el manejo de archivos es la
eliminacin lgica de registros. Esta operacin consiste en marcar algn campo de
manera que indique que el registro ha sido borrado. Se puede disponer algn
campo para tal fin, como en el ejemplo, o bien considerar algn campo con un
valor ilegal, como por ejemplo, un * para nombre y apellido. Los pasos a seguir
son:
solcitar la clave (en este ejemplo la matrcula);
buscar la matricula en el archivo;
si la matrcula no existe;
emitir u n mensaje de error;
sino
marcar el campo que indica qie el registro est borrado;
void bajas (FILE * arch)
{ struct reg alumno;
int k;
clrscr();
printf("Ingresar matricula: ");
getstr(alumno.matricula, 4,4, valido1);
while (strcmp(alumno.matricula,"0000") != 0)
{
k = buscar(alumno.matricula, arch);
if ( k != -1)
{ fseek(arch, k*sizeof(reg), 0);
fread(&alumno, sizeof(reg), 1, arch);
printf("Esta a punto de borrar al alumno");
printf(" %s ",alumno.apel_nom);
getch();
alumno.borrado = 'S';
fseek(arch, k*sizeof(reg), 0);
fwrite(&alumno,sizeof(struct reg),1,arch);
}
else
{ printf("\n\nLa matricula NO existe");
getch();
}
clrscr();
printf("Ingresar matricula: ");
getstr(alumno.matricula, 4,4, valido1);
}
}

31

Archivos

Modificaciones
Esta operacin es muy similar a la baja lgica. Los pasos a seguir son:
solcitar la clave (en este ejemplo la matrcula);
buscar la matricula en el archivo;
si la matrcula no existe;
emitir u n mensaje de error;
sino
solictar nuevos datos;
actualizar los campos que correspondan;
En la siguiente funcin se modifica la calificacin del segundo o tercer examen.
void modificaciones (FILE * arch, int i)
{ struct reg alumno;
int n;
char nota[3];
int k;
n = leer_nro_examen();
clrscr();
printf("Ingresar matricula: ");
getstr(alumno.matricula, 4,4, valido1);
while (strcmp(alumno.matricula,"0000") != 0)
{
k = buscar(alumno.matricula, arch);
if ( k != -1)
{ fseek(arch, k*sizeof(reg), 0);
fread(&alumno, sizeof(reg), 1, arch);
if (alumno.borrado == 'N')
{ printf ("Ingresar la calificacion del examen %d: ", n);
getstr(nota,1,2,valido1);
if (n == 2)
alumno.calif_2 = atoi(nota);
else
alumno.calif_3 = atoi(nota);
fseek(arch, k*sizeof(reg), 0);
fwrite(&alumno,sizeof(struct reg),1,arch);
}
else
{ printf("\n\nLa matricula NO existe");
getch();
}

}
else
{ printf("\n\nLa matricula NO existe");
getch();
}

32

Archivos

clrscr();
printf("Ingresar matricula: ");
getstr(alumno.matricula, 4,4, valido1);
}

int leer_nro_examen()
{ int n;
char cn[2];
clrscr();
printf("ingresar numero de examen: ");
getstr(cn,1,1,valido2);
n = atoi(cn);
return n;
}

Ejercicios
dar de alta un nuevo cliente
eliminar un cliente (un cliente se considera dado de baja si hay un * en su nombre.
dado un cliente modificar sus datos

Ttulo no se
En las secciones anteriores hemos construidos las funciones para crear y
actualizar archivos, as como las de recupracin de la informacin en forma
separada. Como hay muchas funciones comunes a todas ellas: buscar(), valido1(),
abrir(), ahora vamos a compaginarlas de manera que todas sean invocadas desde
un nico main() mediante un menu.

#include
#include
#include
#include
#include

<stdio.h>
<conio.h>
<string.h>
<entrada.h>
<stdlib.h>

FILE *abrir();
void altas (FILE * arch);
void bajas (FILE * arch);
void modificaciones (FILE * arch, int nroexamen);
void mostrar (FILE * arch);
void consulta (FILE * arch);
void informe (FILE * arch);
int valido1(char c);
int valido2(char c);
int buscar (char mat[], FILE * arch);
char menu();

33

Archivos

int leer_nro_examen();
struct reg
{ char matricula[5];
char apel_nom[30];
int calif_1;
int calif_2;
int calif_3;
char borrado;
};
void main()
{
FILE * arch;
char opcion;
int nro;
arch = abrir();
opcion = '0';
while (opcion != '7')
{
opcion = menu();
switch (opcion)
{
case '1':
altas(arch);
break;
case '2':
bajas(arch);
break;
case '3':
modificaciones(arch, nro);
break;
case '4':
mostrar(arch);
break;
case '5':
consulta(arch);
break;
case '6':
informe(arch);
break;
}

}
fclose(arch);
clrscr();
printf("Gracias por usar este programa");
getch();
}
FILE *abrir()
{
/* desarrollada en seccin anterior*/
}
void altas (FILE * arch)

34

Archivos

{
/* desarrollada en seccin anterior*/

void bajas (FILE * arch)


{
/* desarrollada en seccin anterior*/
}
void modificaciones (FILE * arch, int i)
{
/* desarrollada en seccin anterior*/
}
void mostrar (FILE * arch)
{
/* desarrollada en seccin anterior*/
}
void consulta (FILE * arch)
{
/* desarrollada en seccin anterior*/
}
void informe (FILE * arch)
{
/* desarrollada en seccin anterior*/
}
int buscar (char mat[], FILE * arch)
{
/* desarrollada en seccin anterior*/
}
char menu()
{
char opcion;
clrscr();
gotoxy(25,5);
printf ("1. Altas");
gotoxy(25,6);
printf ("2. Bajas");
gotoxy(25,7);
printf ("3. Modificaciones");
gotoxy(25,8);
printf("4. Visualizar");
gotoxy(25, 9);
printf ("5. Consulta");
gotoxy(25,10);
printf ("6. Informes");
gotoxy(25,11);
printf ("7. Terminar");
do {
gotoxy(25,13);
printf("Ingresar opcion: ");

35

Archivos

opcion = getche();
} while ((opcion < '1') || (opcion > '7'));
return opcion;
}
int leer_nro_examen()
{
/* desarrollada en seccin anterior*/
}
int valido1(char c)
{
/* desarrollada en seccin anterior*/
}
int valido2(char c)
{
return ( c >= '2') && (c <= '3');
}

Otra forma ms elegante de actualizar y cargar interactivamente en un


archivo es el proceso que se describe a continuacin. Los pasos a seguir son:
solicitar la clave (en este ejemplo la matrcula);
buscar la matricula en el archivo;
si la matrcula no existe;
altas();
sino
mostrar el registro;
consultar al usuario si es baja o modificacin
si es baja
bajas();
sino
modificacion();
Ejercicio
Coficicar en C el enunciado anterior.
Algoritmos Para Fusin De Archivos
La fusin de archivos consiste en construir un archivo a partir de dos (o ms)
archivos. Tanto los archivos orgenes como el destino deben tener todos el mismo
formato de registro. Supongamos que la comisin 1 y 2 se unen, entonces los dos
archivos deben tambin juntarse. Si los archivos no estn ordenados por ningn
campo escribimos simplemente un archivo al final del otro, pero si los archivos
36

Archivos

estn ordenados por alguno de sus campos, por ejemplo, matrcula podemos
intercalarlos para obtener un tercer archivo ya ordenado. La intercalacin de dos
archivos ordenados consiste en construir a partir de ellos un tercer archivo tambin
ordenado. El proceso de intercalacin se realiza, en forma similar que en el caso de
arreglos, seleccionando sucesivamente los elementos con el mnimo valor de cada
uno de los dos archivos, situndolos en el nuevo. De esta forma el nuevo archivo
tiene todos sus elementos ordenados. El algoritmo bsico de intercalacin de
archivos consiste en comparar la clave de un archivo con la del otro, pasar la
menor al nuevo archivo y avanzar en ese archivo y en el nuevo.
#include <stdio.h>
#include <conio.h>
#include <string.h>

FILE *abrir();
void fusion(FILE *f1, FILE *f2, FILE *f3);
struct reg
{ char matricula[5];
char apel_nom[30];
int calif_1;
int calif_2;
int calif_3;
char borrado;
};
main()
{ FILE *arch1, *arch2, *arch3;
arch1 = abrir();
arch2 = abrir();
arch3 = abrir();
fusion(arch1, arch2, arch3);
fclose(arch1);
fclose(arch2);
fclose(arch3);
}

FILE *abrir()
{ FILE *pf;
char archivo[15];
clrscr();
printf("Ingresar nombre del archivo: ");
gets(archivo);
pf = fopen(archivo,"r+b");
if (pf == NULL)
pf = fopen(archivo,"wb");
return pf;
}

37

Archivos

void fusion (FILE *f1, FILE *f2, FILE *f3)


{
struct reg v1, v2;
fseek(f1,0,0);
fseek(f2,0,0);
fread(&v1,sizeof(reg), 1, f1);
fread(&v2,sizeof(reg), 1, f2);
while(!feof(f1) && !feof(f2))
if (strcmp(v1.matricula, v2.matricula) == -1)
{
fwrite(&v1,sizeof(reg), 1, f3);
fread(&v1,sizeof(reg), 1, f1);
}
else
{
fwrite(&v2,sizeof(reg), 1, f3);
fread(&v2,sizeof(reg), 1, f2);
}
if (feof(f1))
{
fread(&v2,sizeof(reg), 1, f2);
while (!feof(f2))
{
fwrite(&v2,sizeof(reg), 1, f3);
fread(&v2,sizeof(reg), 1, f2);
}
}
else
{ fread(&v1,sizeof(reg), 1, f1);
while (!feof(f1))
{
fwrite(&v1,sizeof(reg), 1, f3);
fread(&v1,sizeof(reg), 1, f1);
}
}
}

Ejercicos
Dados dos archivos, disgmos suc1 y suc 2, que contiene informacin de clienes de dos
sucursales de un banco, construir suc3 formado por los registros de suc1 seguidos por los
registros de suc2.

Algoritmos de Mantenimiento
Entre los algoritmos de mantenimiento estn aquellos que modifican la estructura
de los registros y los de compactacin.
Modificacin De Estructura
Supongamos que tenemos un archivo cuyos registros tienen una estructura reg1, y
debemos agregarle algunos campos que no haban sido previstos (por ejemplo en
el archivo de alumnos debemos agregar la calificacin del examen final), o bien
modificar el tamao de algn campo. Definimos entonces una nueva estrucutrua
38

Archivos

reg2 y dos punteror a archivos, arch1 y arch2. Tambin debemos definir dos
variables, v1 de tipo reg1 y v2 de tipo reg2, El algoritmo para modificar la
estructura consiste en abrir el archivo existente para lectura y otro nuevo para
escritura; leer cada registro del archivo viejo en v1; asignar los campos comunes
entre ambos registros a v2; escribir v2 en el archivo nuevo; cuando se llega al fin
del archivo asociado a arch1 cerrar ambos archivos.
Compactacin
Con compactacin se entiende eliminar fsicamente del archivo, aquellos registros
que han sido eliminados lgicamente. Sean la estructura reg y arch1 y arch2 de
tipo puntero a archivo, y v una variable de tipo reg. El primer archivo se abre para
lectura y el segundo para escritura; se lee de arch1 en v, si el valor de v.borrado
es N (o cualquiera sea la condicin de registro no eliminado) se ejecuta la accin
fwrite(&v, sizeof(reg), 1, arch2), en caso contrario no se efecta ninguna accin;
en ambos casos se continua con el prximo registro; finalmente se cierran ambos
archivos.
Ejercicios
1, En el archivo comis_1 se desea, para cada alumno, guardar la nora del
examen final.
2. Compactar el archivo comis_1.
Ordenacin
La ordenacin de archivos se la conoce como ordenacin externa. Si el archivo es
lo suficientemente pequeo como para que pueda caber en la memoria principal de
la computadora, los pasos a seguir son: 1) leer el archivo en un arreglo; 2) aplicar
un mtodo de ordenacin interna y 3) grabar el arreglo ordenado en el archivo.
Cuando los archivos son muy grandes, demasiado grandes para que puedan caber
en la memoria principal se debe leer porciones del archivo, aplicar un mtodo de
ordenacin interna a cada porcin y generar de esta manera subarchivos
ordenados, los cuales deben ser intercalados para obtener el archivo final.
Un mtodo de ordenacin externa consta de dos fases: ordenacin interna e
intercalacin de archivos. Como el proceso de entrada y salida es mucho ms lento
que las comparaciones en memoria, el costo de un algoritmo de ordenacin
externa no est dado por la cantidad de comparaciones y movimientos en la
memoria principal sino por la cantidad de veces que hay que recorrer el archivo.
En este ltimo punto influye el medio de almacenamiento externo en el cual est
guardado el archivo: por ejemplo, elementos guardados en una cinta magntica
pueden ser accedidos solo en manera secuencial.

39

Archivos

Como hemos dicho la mayora de los mtodos de ordenacin externa usan la


siguiente estrategia: en primer lugar hacer una pasada a travs del archivo a ser
ordenado, dividindolo en bloques de tamao que puedan ser almacenados en la
memoria principal, y ordenar estos bloques. Luego intercalar los bloques
ordenados haciendo varias pasadas por el archivo creando sucesivamente bloques
ordenados cada vez ms grandes, hasta que el archivo entero lo est.
Para la fase de ordenacin interna se usar el mtodo ms rpido segn sea la
distribucin de los datos a ordenar. Para la fase de intercalacin existen varios
mtodos de los cuales trataremos el denominado Intercalacin balanceada de Pvas.
Una intercalacin balanceada de P-vas utiliza 2P archivos auxiliares; P archivos
de entrada y P de salida. Al nmero P se lo denomina grado de la intercalacin.
Supongamos que tenemos un archivo de 9000 registros y que en memoria slo hay
lugar para 1000. Veamos como funciona el algoritmo para distintos valores de P.
P=2
fase de ordenamiento
Leemos los primeros 1000 registros, R0001 . . . R1000, los ordenamos y los grabamos
en el archivo A1; leemos los 1000 registros siguientes, R 1001 . . . R2000 , los
ordenamos y los grabamos en A2; leemos los registros R 2001 . . . R3000 , los
ordenamos y los grabamos en A1 y as sucesivamente. Al terminar la fase
ordenamiento, obtenemos:
A1: R0001 . . . R1000 R2001 . . . R3000 R4001 . . . R5000 R6001 . . . R7000 R8001 . . . R9000
A2: R1001 . . . R2000 R3001 . . . R4000 R5001 . . . R6000 R7001 . . . R8000

donde cada porcin de 1000 registros est ordenada.


fase de intercalacin
paso 1
Aplicamos el algoritmo de intercalacin entre A1 y A2 (slo los primeros 1000
registros de cada uno), y obtenemos en A3 los primeros 2000 registros ordenados.
Luego intercalamos los registros del 2001 al 4000 que los pasaremos al archivo
A4, y as siguiendo,
A3: R0001 . . . R2000 R4001 . . . R6000 R8001 . . . R9000

40

Archivos

A4: R2001 . . . R4000 R6001 . . . R8000

paso 2
En este paso, A3 y A4 pasan a ser los archivos de entrada y A1 y A2 de salida.
A1: R0001 . . . R4000 R8001 . . . R9000
A2: R4001 . . . R8000

paso 3
Nuevamente A1 y A2 son de entrada y A3 y A4 de salida.
A3: R0001 . . . R8000
A4: R8001 . . . R9000

paso 4
A1: R0001 . . . R9000

Obteniendo el archivo entero ordenado.


P=3
fase de ordenamiento
A1: R0001 . . . R1000 R3001 . . . R4000 R6001. . . R7000
A2: R1001. . . .R2000 R4001 . . .R5000 R7001 . . . R8000
A3: R2001 . . . R3000 R5001 . . . R6000 R8001 . . . R9000

fase de intercalacin
paso 1
A4: R0001 . . . R3000

41

Archivos

A5: R3001 . . . R6000


A6: R6001 . . . R9000

paso 2
A1: R0001 . . . R9000

Vemos que para P=2 se necesitaron cuatro pasos de intercalacin, mientras que
para P=3 slo han hecho falta dos. La cantidad de pasos de intercalacin tambin
depende por supuesto de la cantidad de elementos que pueden caber
simultneamente en la memoria principal. Si el archivo es de tamao N y en
memoria se pueden almacenar hasta M registros simultneamente, en la fase de
ordenamiento se construirn S = [N/M] subarchivos ordenados (La notacin [x]
indica el menor entero mayor o igual que x). A mayor S, o sea a menor M, y menor
grado de intercalacin mayor es la cantidad de pasos en la fase de intercalacin y
por consiguiente el proceso ser ms lento.
Durante cada paso de intercalacin el nmero de subarchivos que se obtienen es
aproximadamente el nmero de subarchivos del paso anterior dividido el grado de
la intercalacin (P). Adems, en cada paso casi todos los subarchivos ordenados se
alargan por un factor igual al grado de la intercalacin. Si S es de la forma P k, el
nmero de subarchivos de salida de cada paso de intercalacin es exactamente el
nmero de subarchivos de entrada al paso dividido P. Cada subarchivo de salida es
P veces de largo de cada subarchivo de entrada. Si la fase de ordenamiento interno
produce S subarchivos para ser intercalados, entonces una intercalacin
balanceada, requerir O(logPS) pasos de intercalacin.
Cortes De Control
Supongamos que disponemos de un archivo cuyos campos son: nmero de cliente,
nmero de factura e importe de la factura. Es obvio que el mismo nmero de
cliente podr aparecer varias veces en el archivo, en realidad aparecer tantas
veces como facturas tenga. Sabiendo que el archivo est ordenado por nmero de
cliente, queremos construir a partir de l otro archivo que tenga slo un registro
por cada cliente. Los campos de los registros de este ltimo archivo son nmero de
cliente e importe total.
El archivo est formado por grupos de registros que tienen el mismo valor de la
clave (en este caso mismo nmero de cliente), y cada vez que haya un cambio en
el valor de la clave debemos grabar un registro en el archivo nuevo.

42

Archivos

Archivo Existente
cliente
02
02
02
05
06
06
*

factura
345
678
789
344
348
750

Archivo Nuevo
importe
820.30
345.00
200.50
1000.00
522.50
200.00

cliente
02
05
06
*

importe_total
1365.80
1000.00
722.50

Se sugiere al lector que realice cuidadosamente el seguimiento del siguiente


algoritmo:
#include <stdio.h>
#include <conio.h>
#include <string.h>
FILE *abrir();
void generararch(FILE *f, FILE *f1);
struct reg_1
{
char cliente[3];
char factura[4];
double importe;
};
struct reg_2
{
char cliente[3];
double importe_total;
};
main()
{ FILE *f, *f1;
f = abrir();
f1 = abrir();
generararch(f, f1);
fclose(f);
fclose(f1);
}
void generararch(FILE *f, FILE *f1)
{
struct reg_1 v;
struct reg_2 v1;
char cliente_ant[3];
fseek(f, 0, 0);
fseek(f1, 0, 0);
fread(&v, sizeof(reg_1), 1, f);
while( !feof(f))
{ v1.importe_total = 0;

43

Archivos

strcpy(cliente_ant, v.cliente);
while (!feof(f) && (strcmp (v.cliente, cliente_ant) == 0))
{
v1.importe_total = v1.importe_total + v.importe;
fread(&v, sizeof(reg_1), 1, f);
}
strcpy(v1.cliente, cliente_ant);
fwrite(&v1, sizeof(reg_2), 1, f1);
}

Observar que hay una estructura while para recorrer todo el archivo y otra para
recorrer cada grupo de clientes. Los algoritmos de cortes de control se usan muy
frecuentemente en la programacin de sistemas comerciales, sobre todo en salida
impresa. Generalmente cada vez que se procesa un grupo se requiere un subtotal y
al final de todo el proceso un total general. Supongamos que del archivo anterior
queremos obtener el siguiente listado.
DETALLE DE VENTAS
Cliente

Factura

Importe

02

345
678
789

820.30
345.00
200.50

TOTAL CLIENTE 02

1345.80

05

344

TOTAL CLIENTE 05

1000.00
1000.00

06

348
750

TOTAL CLIENTE 06

522.50
200.00
722.50

TOTAL VENDIDO

2068.30

#include <stdio.h>
#include <conio.h>
#include <string.h>
FILE *abrir();
void listararch(FILE *f);
struct reg_1
{
char cliente[3];
char factura[4];

44

Archivos

double importe;
};
main()
{ FILE *f;
f = abrir();
listararch(f);
fclose(f);
}
void listararch(FILE *f)
{ struct reg_1 v;
char cliente_ant[3];
double total_cliente;
double total;
printf("Clientes
Importe");
total = 0;
fread(&v, sizeof(reg_1), 1,f);
while(!feof(f))
{ total_cliente = 0;
strcpy(cliente_ant, v.cliente);
printf("%s", v.cliente);
while (!feof(f) && (strcmp(v.cliente, cliente_ant) == 0))
{
printf("\n%s
%f",v.factura, v.importe);
total_cliente = total_cliente + v.importe;
fread(&v, sizeof(reg_1), 1,f);
}
printf ("\nTotal cliente %s
%f", cliente_ant,
total_cliente);
total = total + total_cliente;
}
printf("\nTotal vendido
", total);
}

Todos los algoritmos para generar listados con cortes de control tienen una forma
similar. Si los registros tuvieran adems un campo vendedor y el archivo estuviera
ordenado por vendedor y por cada vendedor por cliente, podramos obtener un
corte por vendedor y otro por cliente. Deberamos agregar una variable
total_vendedor (para totalizar las ventas de cada vendedor) y otra vendedor_ant
(para guardar el cdigo del vendedor anterior).
Para poder hacer cortes de control como el enunciado el archivo tiene que estar
ordenado de la siguiente forma :
Clave 3
Clave 2
Clave 1
Archivo

45

Archivos

Dentro del archivo se repite cada valor de la primer clave, a su vez para valores
iguales de la primer clave, se repiten valores de la clave 2, dentro de la clave 2 se
repiten valores de la clave 3 y as siguiendo. Un algoritmo para hacer tantos cortes
de control como claves haya, tiene el siguiente formato general:
acciones 0.a;
leer primer registro;
while (no fin del archivo)
{
acciones 1.a;
while ((no fin del archivo) y (clave1 igual clave1_anterior))
{
acciones 2.a;
while ((no fin de archivo) y (clave1 igual clave1_anterior) y (clave2 igual clave2_anterior))
{ .
.
.
while ((no fin de archivo) y (clave1 igual clave1_anterior) y (clave2 igual clave2 _anterior) y .....
{
procesar registro;
leer prximo registro;
.
.
}.
}
aciones 2.b;
}
acciones 1.b;
}
acciones 0.b

Observar que la cantidad de ciclos while es una ms que la cantidad de claves. Las
acciones 0.a, generalmente imprimen un ttulo y dan valores iniciales a las
variables que calculan totales de todo el archivo. Las acciones 1.a, 2.a, etc. dan
valores iniciales a los subtotales de la clave 1, clave 2 , etc respectivamente y
guardan el valor anterior de la clave. Las acciones del ciclo ms interno son
procesar el registro y leer prximo registro. Las acciones 1.b, 2.b etc., imprimen
los subtotales de la clave respectiva e incrementan los subtotales de un nivel ms
externo. Finalmente las aciones 0.b imprime los totales generales.

46

Archivos

Una Aplicacin Con Archivos Y Arreglos


Supongamos que, en una Universidad, el acceso a la biblioteca est controlado por
un lector de tarjetas. Cada alumno posee una tarjeta, que debe utilizar para ingresar
a la biblioteca. Cada vez que esta tarjeta es insertada en el lector, el programa
controla las entradas, lee las informaciones codificadas en la tarjeta (en particular
matrcula del alumno). Si la persona es autorizada, el programa ordena la apertura
de la puerta e inscribe el nombre del alumno en un archivo diario de control. En
este archivo, cara registro contiene el nmero de la matrcula y aparecen en el
orden de las entradas. Si un mismo alumno ha entrado varias veces a la biblioteca,
habr en el archivo, varios registros con su matrcula. Al final del da se quiere un
listado con el nmero de matrcula y el nmero de visitas efectuadas. Tener en
cuenta que el archivo no est ordenado respecto a matrcula.
Veamos dos posibles soluciones y las ventajas y desventajas de cada una. Si la
cantidad mxima de alumnos que visitan diariamente la biblioteca es, digamos,
100, podemos definir un arreglo de 100 elementos donde cada elemento tiene dos
campos: matricula y cantidad de visitas. El algoritmo es:
inicializar arreglo;
leer registro;
while (no sea el fin de archivo)
{
buscar la matricula en el arreglo;
si (la encontro)
sumarle 1 a cantidad;
sino
{
agregar la matrcula al arreglo;
asignar 1 a cantidad;
}
leer registro
}
imprimir el arreglo;
Este algoritmo es muy rpido pero tiene la desventaja de utilizar un arreglo que, ya
sabemos, necesitamos a priori determinar su tamao. El algoritmo anterior sirve
siempre y cuando la cantidad de alumnos distintos que visitan la biblioteca
diariamente no supere a 100.
La otra forma de resolverlo es ms lenta pero no tenemos restriccin de la cantidad
de alumnos diaria. Ordenamos el archivo por matrcula, para ello aplicamos el
mtodo de ordenacin balanceada de P-vas; de esta manera todos los registros
correspondientes a un mismo alumno quedarn juntos. Luego aplicamos la tcnica
de corte de control recin estudiada.
ejercicio

47

Archivos

codificar el enunciado anterior


Creacin de ndices
En la seccin anterior vimos que para realizar cortes de control es indispensable
que el archivo est ordenado. Adems un archivo ordenado tiene otras ventajas,
por ejemplo podemos hacer una bsqueda binaria en lugar de una secuencial para
encontrar el registro que le corresponde a un valor dado de la clave. Pero mantener
un archivo ordenado es muy costoso porque insertar un registro nuevo en el
archivo implica encontrar, en primer lugar, el lugar donde ubicarlo y luego correr
todos los registros siguientes para liberar el espacio requerido para la insercin.
Vemos, entonces, que hay dos alternativas de trabajo: una posibilidad es trabajar
con el archivo desordenado, esto hace que la insercin de un nuevo registro sea
muy rpida ya que simplemente debemos agregarlo detrs del ltimo, pero es muy
lenta la bsqueda de un valor de la clave y si necesitamos hacer cortes de control
debemos aplicar algn mtodo de ordenacin externa que generalmente son muy
costosos. Otra posibilidad es trabajar con el archivo permanentemente ordenado,
esto tiene ventajas en las bsquedas y algoritmos de cortes de control pero se hace
muy lenta la insercin de nuevos registros. Hay una tercer alternativa que es
construir archivos ndices. Un archivo ndice es un archivo cuyos registros estn
formados, generalmente, por dos campos, la clave y una referencia al registro en
donde se encuentra la informacin correspondiente a ese valor de la clave en el
archivo de datos.
Archivo de datos

Archivo ndice

registro

matricula

apel_nom

calif_1

calif_2

concepto

borrado

matricula

registro

5678

5233

5345

5345

5787

5567

5233

5568

5567

5678

5890

5787

5789

5789

5568

5890

El esquema anterior corresponde al archivo de alumnos y un archivo ndice


ordenado por matrcula.
Una de las ventajas de un archivo ndice es que la adicin de registros es mucho
ms rpida que con un archivo de datos ordenado, siempre y cuando el ndice sea
lo suficientemente pequeo para que pueda ser almacenado completo en la
memoria principal. Como la longitud de cada registro del archivo de ndices es

48

Archivos

pequea, no es difcil cumplir esta condicin para archivos pequeos, conformados


por unos miles de registros.
Un archivo ndice puede crearse junto o despus de crearse el archivo de datos.
Tambin se pueden tener varios archivos ndices, por ejemplo un ndice ordenado
por matrcula y otro por apellido. Si el archivo de datos y los ndices se crean
simultneamente tenemos:
1.
2.
3.
4.

crear los archivos vacos de ndices y de datos


cargar el archivo de ndice en la memoria
actualizar el archivo de datos y el ndice
escribir el archivo ndice de la memoria al disco despus de usarlo

Creacin De Los Archivos de Datos e ndice


Tanto el archivo de ndice como el de datos se crean como archivos vacos.
Carga Del ndice En La Memoria
Se supone que el archivo de ndice es lo suficientemente pequeo para caber en la
memoria principal, de tal manera que se define un arreglo INDICE para
almacenar los registros del archivo de ndices. Por consiguiente la carga de este
archivo consiste, simplemente, en leer el archivo ndice en el arreglo.
Actualizar El Archivo De Datos Y El ndice
Agregar un registro nuevo al archivo de datos requiere que tambin se agregue un
registro al archivo de ndices. El registro con la informacin se agrega al final del
archivo de datos y se inserta en el lugar adecuado (para mantener el orden) un
registro con la clave y la referencia en el arreglo de ndices. La eliminacin de
registros implica la eliminacin de todas las referencias a ese registro en un
sistema de archivos. Si se modifican campos que son claves en los archivos
ndices ser necesario volver a ordenarlos, si los campos modificados no forman
parte de la clave los archivos ndices no se modifican.
Escribir El Archivo ndice De La Memoria Al Disco Despus De Usarlo
Cuando se termina el procesamiento de un archivo con ndices es necesario
escribir el arreglo INDICE de vuelta en el archivo de ndices.
Recuperacin De La Informacin
Si debemos emitir un listado ordenado por la clave del ndice, debemos: leer el
archivo ndice en un arreglo, recorrer el arreglo y obtener la informacin del
registro del archivo de datos indicado en el ndice.

49

Archivos

Si debemos obtener un listado por un campo que no es la clave del archivo ndice,
por ejemplo por nombre y apellido, debemos:
1. a partir del archivo de datos construir un arreglo INDICE que contenga los
valores de la nueva clave y el registro que le corresponde en el archivo de datos
2. ordenar el arreglo INDICE
3. recorrer el arreglo y obtener la informacin del registro del archivo de datos
indicado en el ndice
ndices Demasiados Grandes Para Ser Almacenados En Memoria
Las tcnicas analizadas y, por desgracia, muchas de las ventajas que presentan,
estn sujetos a la suposicin de que el archivo de ndices es lo suficientemente
pequeo para cargase por completo en memoria. Cuando el ndice es demasiado
grande para poder almacenarse en la memoria principal, se deben usar tcnicas
para crear ndices que escapan al mbito de este texto.

Ejercicio adicionales
Agregar de archivos de text
1 y 7 de cranwell
java 10.1, 10.2, 10.3

50

You might also like