Práctica # 12

Anuncio
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
PROGRAMA
EDUCATIVO
Licenciado en
Sistemas
Computacionales
PLAN DE
ESTUDIO
2009-2
CLAVE DE
UNIDAD DE
APRENDIZAJE
11294
NOMBRE DE LA UNIDAD DE APRENDIZAJE
Programación Estructurada
PRÁCTICA
No.
NOMBRE DE LA PRÁCTICA
DURACIÓN
(HORAS)
12
Archivos Binarios
2
1. INTRODUCCIÓN
Un archivo es un conjunto de datos estructurados en una colección de entidades elementales o básicas
denominadas registros que son de igual tipo y constan a su vez de diferentes entidades de nivel más
bajos denominadas campos. Hay dos tipos de archivos, archivos de texto y archivos binarios.
En C, un archivo es un concepto lógico que puede aplicarse a muchas cosas desde archivos de disco
hasta terminales o una impresora.
2. COMPETENCIA
Elaborar programas de cómputo aplicando archivos binarios para el almacenamiento y recuperación
de la información de manera directa con una actitud positiva y honesta.
3. FUNDAMENTO
Para trabajar con un archivo se asocia una estructura especial de tipo FILE con un archivo especifico
realizando una operación de apertura. Una vez que el archivo está abierto, la información puede ser
intercambiada entre este y el programa.
El puntero a un archivo es el hilo común que unifica el sistema de E/S con un buffer. Un puntero a un
archivo es un puntero a una información que define varias cosas sobre él, incluyendo el nombre, el
estado y la posición actual del archivo. En esencia identifica un archivo específico y utiliza la secuencia
asociada para dirigir el funcionamiento de las funciones de E/S con buffer. Un puntero a un archivo es
una variable de tipo puntero al tipo FILE que se define en stdio.h. Un programa necesita utilizar punteros
a archivos para leer o escribir en los mismos. Para obtener una variable de este tipo se utiliza una
secuencia como la siguiente:
FILE *puntero_archivo;
Formuló
Revisó
José Alfredo Abad Padilla
Josefina Mariscal Camacho
Nombre y Firma del Maestro
Nombre y Firma del Responsable
de Programa Educativo
Página 1 de 8
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
Apertura de un archivo
La función fopen() abre una secuencia para que pueda ser utilizada y la asocia a un archivo. Su
prototipo es:
FILE *fopen(const char nombre_archivo, const char modo);
Donde nombre_archivo es una cadena de caracteres que representa un nombre valido de archivo y
puede incluir una especificación del directorio. Por su parte, la cadena modo determina como se abre
el archivo.
Si se usa fopen() para abrir un archivo para escritura, modo w, entonces cualquier archivo existente se
sobrescribirá y si no existe un archivo con el mismo nombre, entonces se creará. Si se quiere añadir al
final del archivo entonces debe usar el modo a. Si se usa a y no existe el archivo lo crea. La apertura de
un archivo para las operaciones de lectura, modo r, requiere que exista el archivo. Si no existe, fopen()
devolverá un error.
Cierre de un archivo
La función fclose() cierra una secuencia que fue abierta mediante una llamada a fopen(). Escribe toda
la información que todavía se encuentre en el buffer en el archivo y realiza un cierre formal del archivo a
nivel del sistema operativo. Un error en el cierre de una secuencia puede generar todo tipo de
problemas, incluyendo la pérdida de datos, destrucción de archivos y posibles errores intermitentes en el
programa. El prototipo de esta función es:
int fclose(FILE *puntero_archivo);
Funciones para manipular un archivo
La función feof() determina cuando se ha alcanzado el fin del archivo. La función tiene el siguiente
prototipo:
int feof(FILE *puntero_archivo);
La función rewind() pone el indicador de posición al principio del archivo indicado por su argumento. Su
prototipo es:
void rewind (FILE *puntero_archivo);
La función ferror() determina si se ha producido en error en una operación sobre un archivo. Su prototipo
es:
int ferror(FILE *puntero_archivo);
Devuelve cierto si se ha producido un error durante la última operación sobre el archivo. En caso
contrario, devuelve falso. Debido a que cada operación sobre el archivo actualiza la condición de error,
se debe llamar a ferror() inmediatamente después de la operación de este tipo; si no se hace así, el error
puede perderse.
La función remove() borra el archivo especificado. Su prototipo es el siguiente:
int remove(char *nombre_archivo);
Devuelve cero si tiene éxito. Si no un valor distinto de cero.
Página 2 de 8
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
La función fflush() escribe todos los datos almacenados en el buffer sobre el archivo asociado a
puntero_archivo. Su prototipo es:
int fflush(FILE *puntero_archivo);
Archivos Binarios
Un archivo binario es una secuencia de bytes que tienen una correspondencia uno a uno con un
dispositivo externo. Así que no tendrá lugar ninguna traducción de caracteres. Además, el número de
bytes escritos (leídos) será el mismo que los encontrados en el dispositivo externo. Ejemplos de estos
archivos son Fotografías, imágenes, texto con formatos, archivos ejecutables (aplicaciones), etc.
Lectura de un archivo binario
Las funciones fread() y fwrite() pueden leer y escribir bytes desde los archivos y hacia los archivos,
respectivamente. Los prototipos de estas funciones son:
size_t fread(void *registro, size_t tamaño_registro, size_t cantidad_registros, FILE *puntero_archivo);
size_t fwrite(const void *registro, size_t tamaño_registro, size_t cantidad_registros, FILE *puntero_archivo);
La función fread()
Esta función lee un bloque de un flujo de datos "puntero_archivo". Efectúa la lectura de un arreglo de
elementos "cantidad_registros", cada uno de los cuales tiene un tamaño definido por "tamaño_registro".
Luego los guarda en el bloque de memoria especificado por "registro". El indicador de posición de byte
avanza hasta leer la totalidad de bytes. Si esto es exitoso la cantidad de bytes leídos es
(tamaño_registro*cantidad_registros).
La función fwrite()
Es capaz de escribir hacia un archivo uno o varios registros de la misma longitud almacenados a partir
de una dirección de memoria determinada. El valor de retorno es el número de registros escritos, no el
número de bytes. Los parámetros son: un puntero a la zona de memoria de donde se obtendrán los
datos a escribir, el tamaño de cada registro, el número de registros a escribir y un puntero FILE del
archivo al que se hará la escritura.
Manejo del desplazamiento sobre el archivo
La función fseek()
Esta función sitúa el puntero (cursor) de un archivo en una posición deseada, trabaja para modo binario
y texto.
int fseek(FILE *puntero_archivo, long offset, int origen);



puntero_archivo es un puntero a la estructura del archivo.
offset es un entero largo que especifica el número de bytes, a partir de la posición de origen,
donde se colocará el cursor.
origen es un número entero que especifica la posición de origen al cual se le suma el offset.
Puede ser:
SEEK_SET: El origen es el comienzo del archivo
SEEK_CUR:El origen es la posición actual
SEEK_END:El origen es el final del archivo
Página 3 de 8
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
La función ftell()
Esta función regresa la posición actual del puntero (cursor) de un archivo.
-1L.
Si ocurre un error regresa un
long int ftell(FILE *puntero_archivo);
El siguiente ejemplo se introduce información para una agenda, cuando se quiere terminar la captura
de información se deja en blanco el nombre (ENTER), posterior se abre el archivo y se lee su contenido.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char nombre[20];
char apellido[20];
int telefono;
}Datos;
void main()
{
FILE *archivo;
Datos registro;
//agregar b en el modo para indicar que se trata de archivos binarios
archivo = fopen( "nombres.bin", "ab" );
system("clear");
do {
printf( "Nombre: " );
gets(registro.nombre);
if (strcmp(registro.nombre,""))
{
printf( "Apellido: " );
gets(registro.apellido);
printf( "Telefono: " );
gets(registro.telefono);
//se guarda el registro en el archivo, 1 solo registro
fwrite( &registro, sizeof(Datos), 1, archivo );
}
} while (strcmp(registro.nombre,"")!=0);
fclose( archivo );
system("clear");
printf("Contenido del archivo\n");
archivo = fopen( "nombres.bin", "rb" );
while (!feof(archivo)) {
//se lee un registro si se pudo leer regresara un 1, ya que se instruye que se lea de 1 en 1
if (fread( &registro, sizeof(Datos), 1, archivo )) {
printf( "Nombre: %s\n", registro.nombre );
printf( "Apellido: %s\n", registro.apellido);
printf( "Telefono: %s\n", registro.telefono);
}
}
fclose( archivo );
}
Página 4 de 8
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
El siguiente ejemplo utiliza el archivo binario “nombres.bin” creado en el ejercicio anterior y ordena la
información por apellido.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char nombre[20];
char apellido[20];
int telefono;
}Datos;
void main()
{
FILE *archivo;
Datos registro, aux;
long cuantos;
int x, y;
//se abre para lectura y escritura
archivo = fopen( "nombres.dat", "r+b" );
//se posiciona el cursor 0 bytes a partir del final del archivo
fseek(archivo, 0, SEEK_END);
//se pide la cantidad de bytes y se divide entre el tamano de la estructura
//para saber cuantas estructuras (personas) estan grabadas
cuantos = ftell(archivo) / sizeof(Datos);
//regresamos al inicio el archivo
rewind(archivo);
//Metodo de ordenacion
for(x = 1; x<cuantos; x++)
for(y = 0; y<cuantos-x; y++)
{
fseek(archivo, sizeof(Datos)*y, SEEK_SET);
fread(&registro, sizeof(Datos), 1, archivo);
fseek(archivo, sizeof(Datos)*(y+1), SEEK_SET);
fread(&aux, sizeof(Datos), 1, archivo);
if(strcasecmp(registro.apellido, aux.apellido)>0)
{
//se graba las estructuras en orden inverso
fseek(archivo, sizeof(Datos)*y, SEEK_SET);
fwrite(&aux, sizeof(Datos), 1, archivo);
fseek(archivo, sizeof(Datos)*(y+1), SEEK_SET);
fwrite(&registro, sizeof(Datos), 1, archivo);
}
}
rewind(archivo);
system("clear");
printf("Contenido del archivo\n");
while (fread(&registro, sizeof(Datos), 1, archivo )) {
printf( "Nombre: %s\n", registro.nombre );
printf( "Apellido: %s\n", registro.apellido);
printf( "Telefono: %d\n", registro.telefono);
}
fclose( archivo );
}
Página 5 de 8
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
El siguiente ejemplo utiliza el archivo binario “nombres.bin” creado en el primer ejercicio y elimina un
registro buscando por apellido.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char nombre[20];
char apellido[20];
int telefono;
}Datos;
void main()
{
FILE *archivo, *archivoaux;
Datos registro;
char apellbus[20];
int eliminado = 0;
//se abre para lectura
archivo = fopen("nombres.dat", "rb");
//se crea un archivo auxiliar
archivoaux = fopen ("temporal.dat", "wb");
system("clear");
printf("Apellido de la persona a eliminar: ");
gets(apellbus);
while (fread(&registro, sizeof(Datos), 1, archivo ))
if(strcasecmp(apellbus,registro.apellido)==0)
{
printf("Registro de persona con apellido %s eliminado\n", registro.apellido);
eliminado = 1;
}
else
{
//se envia la informacion que no se quiere eliminar a un archivo auxiliar
fwrite(&registro, sizeof(Datos), 1, archivoaux);
}
fclose(archivo);
fclose(archivoaux);
//si hubo eliminados se renombra el archivo auxiliar si no solo se elimina
if (eliminado)
{
remove("nombres.dat");
rename("temporal.dat", "nombres.dat");
}
else
{
remove("temporal.dat");
printf("No existe %s en el archivo\n", apellbus);
}
getchar();
system("clear");
printf("Contenido del archivo\n");
archivo = fopen("nombres.dat", "rb");
while (fread(&registro, sizeof(Datos), 1, archivo )) {
printf( "Nombre: %s\n", registro.nombre );
printf( "Apellido: %s\n", registro.apellido);
printf( "Telefono: %d\n", registro.telefono);
}
fclose( archivo );
}
Página 6 de 8
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
4. PROCEDIMIENTO (DESCRIPCIÓN)
A) EQUIPO NECESARIO
MATERIAL DE APOYO
Equipo de cómputo con Linux instalado o
con conexión a algún servidor de Linux
Apuntes
B) DESARROLLO DE LA PRÁCTICA
Lea cuidadosamente los siguientes planteamientos, identifique las entradas y la salida para presentar
una solución en lenguaje C.
1. Utilice el código de los ejemplos mostrados en la práctica y construya una aplicación llamada
agenda, en la cual se almacenaran también el correo electrónico, el teléfono de casa, del
trabajo y el móvil y un grupo(amigos, familiares, otros), de acuerdo al grupo estarán . Construir un
menú con las siguientes opciones:
a) Alta de contacto
b) Baja de contacto
c) Consultar
1. Toda la agenda
2. Solo un contacto (por apellido paterno)
3. Regresar
d) Ordenar (si dos apellidos coinciden se tomara en cuenta el nombre para ordenar)
e) Salir.
C) CÁLCULOS
Preguntas sobre la práctica de forma INDIVIDUAL, que hará el maestro al finalizar la práctica a cada
alumno.
5. RESULTADOS Y CONCLUSIONES
El resultado de las prácticas deberá visualizarse en pantalla.
6. ANEXOS
Modos de apertura de archivos
Página 7 de 8
UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA
FACULTAD DE INGENIERÍA MEXICALI
Funciones para la manipulaciones de archivos
7. REFERENCIAS
Manual de C.
Héctor Tejeda Villela. Hill. 2005
Página 8 de 8
Descargar