Professional Documents
Culture Documents
FUNDAMENTOS DE PROGRAMACIN
Tema 7
Estructuras Externas
__________________________________________________________________________________________________________
Estructuras Externas
0
1. INTRODUCCIN.
En la mayora de las aplicaciones, muy especialmente en las de gestin, es
necesario almacenar informacin de forma permanente. Hasta ahora, todos los
mecanismos de almacenamiento de informacin que hemos estudiado (constantes,
variables, estructuras, vectores, punteros, etc.) son voltiles. Es decir, cuando el
programa que los utiliza termina su ejecucin desaparecen y la informacin contenida
en ellos se pierde.
Para resolver este problema se necesitan estructuras de datos externas al
programa. Al ser externas no desaparecern con l. Adems, si dichas estructuras
externas se almacenan en un dispositivo no voltil (un disco, una cinta, un CD-ROM,
...), se puede decir, siempre con una seguridad relativa, que la informacin permanecer
aunque se desconecte el ordenador de la alimentacin, desaparezca el programa que lo
cre, etc.
La estructura de datos externa bsica es el fichero (archivo).
2. CORRIENTES.
En C, los dispositivos tradicionales como terminales, unidades de disco o cinta,
puertos e impresora, son tratados como ficheros. Esto es posible porque, sea cual sea la
naturaleza del dispositivo externo, el sistema de almacenamiento temporal de ficheros
los convierte en un dispositivo lgico denominado corriente (canal, flujo o stream).
Debido a que la corriente es casi independiente del dispositivo que la genera, las
funciones de biblioteca que escriben un fichero en disco pueden ser utilizadas, con las
oportunas variaciones, para producir una salida por impresora o por la consola.
A estos efectos, la entrada estndar de datos (por teclado) se asocia con un
fichero con nombre stdin (Standard Input o entrada de datos estndar), y la salida por
pantalla con stdout (Standard Output o salida de datos estndar).
Fundamentalmente, C distingue dos tipos de corrientes:
Corrientes de texto
Corrientes binarias
__________________________________________________________________________________________________________
Estructuras Externas
1
Una corriente binaria, en cambio, es una secuencia de bytes que tiene una
correspondencia uno a uno con los del dispositivo externo. Es decir, no se producen
conversiones de caracteres. Adems, la cantidad de caracteres escritos o ledos coincide
con la del dispositivo externo. En este caso, cada registro es de longitud fija. As, la
informacin presente en la memoria y la del disco coinciden unvocamente, carcter a
carcter o byte a byte.
3. FICHEROS.
En C, un fichero es un concepto lgico que en el momento de su apertura se
asocia a una corriente y se disocia de sta en el momento del cierre del fichero.
Dependiendo del soporte de almacenamiento, no todos los ficheros tienen las
mismas posibilidades. Por ejemplo, un fichero de disco puede soportar el acceso directo,
mientras que un mdem no. Esto muestra un aspecto importante sobre el sistema de E/S
en C: todas las corrientes son iguales, pero todos los ficheros no.
Si el fichero soporta el acceso directo, la apertura de ese fichero inicializa un
indicador de posicin del fichero al principio del mismo. Cuando se lee o se escribe
cada carcter desde o en el fichero, el indicador de posicin se incrementa, asegurando
la progresin a travs del mismo.
La parte ms pequea de un disco a la que se puede acceder se denomina sector.
La informacin se escribe o se lee desde el disco sector a sector. Por tanto, se va a leer
un sector completo de datos incluso si el programa slo necesita un byte. Estos datos se
colocan en una regin de memoria denominada buffer que puede utilizar el programa.
Cuando los datos se envan a un fichero de disco, se colocan en el buffer hasta que se
acumula un sector completo de informacin y, en ese momento, se escriben fsicamente
en el fichero.
Se puede disociar una corriente de fichero especfico mediante la operacin de
cierre. El cierre supone escribir cualquiera de los contenidos de su buffer asociado en el
dispositivo externo. Este proceso se denomina vaciado de buffer y garantiza que no
quede informacin en l.
Al comienzo de la ejecucin de un programa se abren 5 corrientes de texto
predefinidas:
Corriente
stdin
stdout
stderr
Dispositivo
Teclado
Pantalla
Pantalla
__________________________________________________________________________________________________________
Estructuras Externas
2
stdaux (*)
stdprn (*)
Los tres primeros flujos estn definidos por el estndar ANSI de C y todo el
cdigo que los utilice es totalmente portable. Los dos ltimos son especficos de
determinados compiladores (*).
NOTA:
Las entradas/salidas estndar de C para manejo de ficheros utilizan punteros a
corrientes asociadas a dispositivos/ficheros, en cambio, las E/S UNIX a nivel de
sistema utilizan descriptores de ficheros (handles).
En este captulo slo vamos a usar la forma estndar de C y el prximo curso
estudiaris la forma UNIX.
As pues, todas las funciones y constantes que vamos a estudiar se encuentran en la
biblioteca stdio.h.
4. MANEJO DE FICHEROS
En la utilizacin de ficheros desde un programa en C se tienen que tener en
cuenta las siguientes operaciones:
1. Declaracin de una variable que identifique el canal de escritura o lectura. Es el
identificador interno del fichero.
2. Declaracin de una variable que contenga el nombre del fichero en disco o cinta.
Es el identificador externo del fichero.
3. Asignacin del identificador externo al identificador interno. Esta operacin se
conoce como apertura de un canal de E/S. En esta accin es necesario indicar
el tipo de fichero (de texto o binario) y el modo de apertura (si va a ser slo de
lectura, si, en cambio, permite aadir registros, etc.).
4. Escritura y/o lectura de datos sobre el fichero.
5. Cierre del fichero, eliminando el canal anteriormente abierto.
Declarar un variable de tipo puntero a fichero (FILE*) que seala hacia una
estructura interna que se refiere al fichero.
Su prototipo es:
FILE *fopen(char *nombre_fichero, char *modo);
Donde nombre_fichero es el nombre externo del fichero a abrir y modo es una
cadena que ndica la forma en que se quiere abrir el fichero, puede ser una de las
siguientes:
Modo
r
w
a
r+
w+
a+
Interpretacin
Abrir slo para lectura. Produce un error si el fichero no existe.
Crear para escritura. Si el fichero ya existe ser machacado.
Aadir. Abre para escribir al final del fichero, o crear para escritura si el fichero
no existe.
Abre para actualizacin. Esto es, lectura y escritura. Produce error si el fichero
no existe.
Crea un nuevo fichero para actualizacin. Si el fichero ya existe es machacado.
Abre para actualizacin al final del fichero o crea el archivo si este no existe.
Las operaciones con ficheros las estudiaremos ms adelante. Por ahora, en nuestro
ejemplo slo debes observar la lgica del proceso, donde se usan las siguientes
funciones:
- feof()
Determina si se ha llegado al final del fichero
- fgets()
Lee la siguiente lnea del fichero de texto de entrada
- fputs()
Escribe una lnea en el fichero de texto de salida
Por ltimo, y no menos importante, tendremos que cerrar el fichero con la
funcin fclose().
Cerrar el fichero es muy importante ya que mientras que el mismo est abierto se
mantienen una zona de almacenamiento intermedio (buffer) en memoria parar acelerar
el acceso a la informacin del fichero. Si no lo cerramos corremos el riesgo de perder
esta informacin intermedia que todava no ha sido escrita a disco y de no liberar estas
zonas de memoria. Para cerrar un flujo utilizamos fclose() pasndole en nombre del
flujo. Su prototipo es el siguiente:
int fclose(FILE *fichero);
Que devuelve 0 si se ha cerrado con xito o EOF si se ha producido algn tipo
de error.
Hay tambin otra funcin fcloseall(), la cual cierra todos los flujos
abiertos excepto los predefinidos (stdin, stdout, stdprn, stderr y stdaux). Su forma es:
int fcloseall(void);
Que devuelve en nmero total de flujos cerrados o EOF si ha habido error.
FILE *f;
char nombre_fichero[30];
printf("Introduzca el nombre del fichero a presentar: ");
scanf("%s",nombre_fichero); fflush(stdin);
if ((f=fopen(nombre_fichero,"r"))==NULL)
{
printf("El fichero %s no existe",nombre_fichero);
getchar();
}
else
{
while (!feof(f))
fputc(getc(f),stdout);
getchar();
fclose(f);
}
}
Escritura/lectura formateada.
scanf("%d",&cantidad); fflush(stdin);
fprintf(f,"%3s %d %d",codigo,precio,cantidad);
printf("Introduzca el cdigo (FIN *): ");
scanf("%s",codigo); fflush(stdin);
}
fclose(f);
// Lectura del fichero creado anteriormente
f=fopen("ventas.txt","r");
while (!feof(f))
{
fscanf(f,"%3s %d %d",codigo,&precio,&cantidad);
printf("Cdigo:%s Precio:%d Cantidad:%d",
codigo,precio,cantidad);
}
getchar();
fclose(f);
}
}
{
char nombre[25];
char direccion[30];
char telefono[12];
int edad;
};
void main(void)
{
registro agenda;
FILE *f;
if ((f=fopen("agenda.dat","wb"))==NULL)
{
printf("No es posible crear el fichero");
getchar();
}
else
{
// Creacin del fichero
printf("Introduzca nuevo nombre (FIN *): ");
gets(agenda.nombre);
while (strcmp(agenda.nombre,"*"))
{
printf("Introduzca direccin: ");
gets(agenda.direccion);
printf("Introduzca telfono: ");
gets(agenda.telefono);
printf("Introduzca edad: ");
scanf("%d",&agenda.edad);fflush(stdin);
fwrite(&agenda,sizeof(agenda),1,f);
printf("Introduzca nuevo nombre (FIN *): ");
gets(agenda.nombre);
}
fclose(f);
// Lectura del fichero creado anteriormente
f=fopen("agenda.dat","rb");
printf("%-25s %-30s %-12s Edad\n",
"Nombre","Direccin","Telfono");
while (!feof(f))
{
fread(&agenda,sizeof(agenda),1,f);
printf("%-25s %-30s %-12s %d\n",
agenda.nombre,agenda.direccion,
agenda.telefono,agenda.edad);
}
getchar();
fclose(f);
}
}
En el ejemplo anterior hemos visto que todos los registros del fichero tienen el
mismo tamao, por tanto, es posible acceder a un determinado registro sin necesidad de
acceder a todos los anteriores; es decir, en lugar de realizar un acceso secuencial,
controlado por la funcin feof(), como hemos visto en todos los ejemplos anteriores,
es posible realizar lo que se denomina acceso directo o aleatorio.
__________________________________________________________________________________________________________
Estructuras Externas
11