Bitácora del desarrollo de mi clase de C++, en el que publicaré el material de la clase y recibiré comentarios y sugerencias de mis alumnos.

miércoles, 9 de mayo de 2007

10.2 Archivos de Acceso Aleatorio

Archivos de acceso directo o aleatorio
La función fwrite transfiere a un archivo un número especificado de bytes empezando en una posición especificada de memoria. Los datos se escriben al principio de la posición en el archivo indicada mediante el apuntador de posición de un archivo. La función fread transfiere un número especificado de bytes de la posición en el archivo, especificado por el apuntador de posición de archivo, a un área en memoria empezando a partir de una dirección especificada. Por ejemplo, para escribir un entero, en vez de especificar:

fprintf(cuentaPtr, “%d”, numero);
para escribir el mismo número de tipo int, se puede especificar:
fwrite( &numero, sizeof(int), 1, cuentaPtr);
más adelante ese dato puede ser leído con la función fread.

El primer parámetro de fprintf es la dirección de la variable a escribir en disco, el segundo el tamaño de bytes del dato que se va a escribir (devuelto por la función sizeof), el tercer parámetro es el número de datos que se van a escribir del tamaño especificado (por lo común será 1) y el último es el apuntador al archivo que se abrió para escritura o modificación.

Para tener datos de tamaño fijo en los archivos y lo que formalmente serán registros del archivo se crea una estructura, es decir, un nuevo tipo de dato definido por el usuario y compuesto por uno o varios tipos de datos con sus nombres de campo respectivos.

La declaración de un tipo struct se hace antes de la función main de la siguiente manera:

struct nombreEstructura
{
tipo1 campo1;
tipo2 campo2;
tipo3 campo3;
};

Por ejemplo, para crear una estructura que permita almacenar los datos de un cliente puede declararse de la siguiente manera:

struct DatosCliente
{
int cuenta;
char apellido[15];
char nombre[10];
float saldo;
};

De este modo se crea una estructura de nombre DatosCliente con los campos descritos, en el programa se podrán declarar variables de tipo DatosCliente y para acceder a cada uno de los campos se utilizara la notación registro.campo. La declaración de una variable de este tipo se hará:

struct DatosCliente micliente;

De esta manera la variable micliente tiene los cuatro campos definidos para el tipo de estructura, y el nombre del cliente se accede con la siguiente línea:

micliente.nombre

El uso de una estructura y de las funciones fread, fwrite y fseek será básicamente la diferencia entre programar para utilizar un archivo secuencial y un archivo de acceso directo.
Cómo crear un archivo de acceso directo.

/* Creacion de un archivo de acceso directo */
#include (stdio.h)
#include (conio.h)
struct DatosCliente
{
int cuenta;
char apellido[15];
char nombre[10];
float saldo;
};

main( )
{
int i;
struct DatosCliente clienteNulo = {0,"","",0.0};
FILE *cuentaPtr;

if ((cuentaPtr = fopen("cliente.dat","w")) == NULL)
printf("No se puede abrir el archivo\n");
else
{
/* Escritura de 100 registros en “blanco”*/
for (i=1; i<= 100; i++)
fwrite( &clienteNulo, sizeof(struct DatosCliente),1, cuentaPtr);
fclose(cuentaPtr);
}
getch ( );
return 0;
}

Cómo escribir y leer datos de un archivo de acceso directo
La introducción de los datos será mediante la misma función fwrite, donde lo que se escribe es la variable del tipo de la estructura deseada, con el tamaño de la misma estructura y el apuntador al archivo. Cada dato debe ser llenado con scanf al campo deseado de la misma estructura. A continuación se presenta un ejemplo de captura de datos y escritura al archivo.

/* Escribiendo a un archivo de acceso aleatorio */
#include (stdio.h)
#include (stdio.h)
struct DatosCliente
{
int cuenta;
char apellido[15];
char nombre[10];
float saldo;
};

main( )
{
/* la variable cliente de tipo DatosCliente servirá para
asignar los almacenar los valores para cada cliente introducido */
struct DatosCliente cliente;
FILE *cuentaPtr;
if ((cuentaPtr = fopen("cliente.dat","r+")) == NULL)
printf("No se puede abrir el archivo\n");
else
{
printf("Introduzca numero de cuenta"
" (1 a 100), 0 para finalizar)\n?");
scanf("%d", &cliente.cuenta);
while (cliente.cuenta != 0)
{
printf("Introduzca el apellido, nombre y saldo\n? ");
scanf("%s%s%f", cliente.apellido, cliente.nombre, &cliente.saldo);
fseek(cuentaPtr, (cliente.cuenta - 1) *
sizeof(struct DatosCliente), SEEK_SET);
fwrite(&cliente, sizeof(struct DatosCliente), 1, cuentaPtr);
printf("Intruduzca n{umero de cuenta\n? ");
scanf("%d", &cliente.cuenta);
}
}
fclose(cuentaPtr);
getch ( );
return 0;
}

La lectura de cada registro en el archivo se hará con la función fread, cuyos parámetros son: la variable que almacena los datos leídos del archivo, el tamaño de la estructura o del tipo de dato, el número de datos a leer y el apuntador al archivo.

/* Leyendo de un archivo de acceso aleatorio */
#include (stdio.h)
#include (conio.h)
struct DatosCliente
{
int cuenta;
char apellido[15];
char nombre[10];
float saldo;
};
main( )
{
struct DatosCliente cliente;
FILE *cuentaPtr;
clrscr();
if ((cuentaPtr = fopen("cliente.dat","r")) == NULL)
printf("No se puede abrir el archivo\n");
else
{
printf("%-8s%-16s%-11s%10s\n", "Cuenta", "Apellido", "Nombre",
"Saldo");
while (!feof(cuentaPtr))
{
fread(&cliente, sizeof(struct DatosCliente), 1, cuentaPtr);
if (cliente.cuenta != 0)
printf("%-8d%-16s%-1s%10.2f\n", cliente.cuenta,
cliente.apellido, cliente.nombre, cliente.saldo);
}
}
fclose(cuentaPtr);
getch();
return 0;
}

0 comentarios:

Publicar un comentario

Suscribirse a Enviar comentarios [Atom]

<< Inicio