Para abrir un archivo en un programa escrito en C, es necesario utilizar la funcin fopen(), la cual recibe dos parmetros, el nombre del archivo y el modo de apertura del archivo. Los modos de apertura se describen a continuacin.
MODO DESCRIPCIN r Abrir un archivo para lectura. w Crear un archivo para escritura. Si el archivo ya existe se pierde el contenido actual. a Agregar, abrir o crear un archivo para escribir al final del mismo. r+ Abrir un archivo para actualizar (leer y escribir). w+ Crear un archivo para actualizar, si el archivo ya existe se pierde el contenido actual. a+ Agregar, abrir o crear un archivo para actualizar, la escritura se efectuar al final del archivo.
A continuacin se presenta un ejemplo de creacin de un archivo secuencial:
/* Creacion de un archivo de acceso secuencial */ #include (stdio.h) #include (conio.h) main( ) { int cuenta; char nombre[30]; float saldo; FILE *cuentaPtr; if ((cuentaPtr = fopen("cliente.dat","w")) == NULL) printf("No se puede abrir el archivo\n"); else { printf("Introduzca cuenta, nombre y saldo.\n"); printf("Introduzca EOF para terminar.\n"); printf("? "); scanf("%d%s%f", &cuenta, nombre, &saldo); while (!feof(stdin)) { fprintf(cuentaPtr, "%d %s %.2f\n", cuenta, nombre,saldo); printf("? "); scanf("%d%s%f", &cuenta, nombre, &saldo); } fclose(cuentaPtr); } getch ( ); return 0; }
El enunciado FILE *cuentaPtr; establece que cuentaPtr es una apuntador a una estructura de tipo FILE. Cada archivo abierto debe tener un apuntador declarado por separado del tipo FILE, que es utilizado para referirse al archivo.
La lnea if ((cuentaPtr = fopen("cliente.dat","w")) == NULL) nombra el archivo cliente.dat, para ser utilizado por el programa y establece una comunicacin con el archivo a travs del apuntador, en este caso el archivo se abre para escritura. La estructura if se utiliza para determinar si el apuntador al archivo cuentaPtr es NULL, es decir, que el archivo no est abierto. Si es NULL, se imprime un mensaje de error y el programa termina, de lo contrario la entrada es procesada y escrita al archivo.
La lnea while (!feof(stdin)) utiliza la funcin feof para determinar si el indicador de fin de archivo est definido para el archivo a que se refiere stdin. El indicador de fin de archivo le informa al programa que ya no hay ms datos a procesar., el indicador de fin de archivo est definido para la entrada estndar cuando el usuario introduce la combinacin de teclas de fin de archivo (Control-Z). La estructura while continuar ejecutndose hasta que se defina el indicador de fin de archivo.
El enunciado fprintf(cuentaPtr, "%d %s %.2f\n", cuenta, nombre,saldo); escribe datos al archivo cliente.dat, que es al que apunta el apuntador cuentaPtr. Los datos pueden ser recuperados ms tarde mediante un programa diseado para leer el archivo.
Al terminar de ejecutar al programa compruebe la creacin del archivo cliente.dat. Desde el explorador de Windows o saliendo al smbolo de sistema mediante la orden File- Dos shell, verifique la existencia y el contenido del archivo cliente.dat. Si se desea que el archivo sea creado en la unidad A:, el parmetro de la funcin fopen debe ser a:cliente.dat, de otra manera se crear en el directorio actual (generalmente C:\TC\BIN).
La funcin fclose() cierra siempre el archivo al cual apunta el apuntador enviado como parmetro, en este caso fclose(cuentaPtr) cierra el archivo cliente.dat.
Cmo leer datos de un archivo de acceso secuencial Una vez que se ha creado el arcihvo, la lectura puede resultar ms cmoda, pues las diferencias con la creacin del archivo son nicamente el modo de apertura del archivo r, y la manera en que se leen los datos mediante la funcin fscanf.
La funcin fscanf, se le indica de qu archivo se leern los datos, mandndole como parmetro el apuntador a FILE, en este caso cuentaPtr, la cadena de control para indicarle qu tipo de datos leer del archivo, y la direccin de las variables a las que asignar los valores ledos (tal como a scanf). Obviamente que si el archivo tiene una ubicacin diferente a la actual, el parmetro de nombre de archivo en la funcin debe tener la ruta completa, por ejemplo fopen(A:CLIENTE.DAT, r);
A continuacin se presenta el ejemplo de lectura del archivo creado en el apartado anterior.
/* Leyendo datos de un archivo de acceso secuencial */ #include (stdio.h) #include (conio.h) main( ) { int cuenta; char nombre[30]; float saldo; FILE *cuentaPtr;
if ((cuentaPtr = fopen("cliente.dat","r")) == NULL) printf("No se puede abrir el archivo\n"); else { printf("%-10s%-13s%s\n","Cuenta","Nombre","Saldo"); fscanf(cuentaPtr,"%d%s%f",&cuenta, nombre, &saldo);
Archivos de Acceso Aleatorio Archivos de acceso directo o aleatorio La funcin fwrite transfiere a un archivo un nmero especificado de bytes empezando en una posicin especificada de memoria. Los datos se escriben al principio de la posicin en el archivo indicada mediante el apuntador de posicin de un archivo. La funcin fread transfiere un nmero especificado de bytes de la posicin en el archivo, especificado por el apuntador de posicin de archivo, a un rea en memoria empezando a partir de una direccin especificada. Por ejemplo, para escribir un entero, en vez de especificar:
fprintf(cuentaPtr, %d, numero); para escribir el mismo nmero de tipo int, se puede especificar: fwrite( &numero, sizeof(int), 1, cuentaPtr); ms adelante ese dato puede ser ledo con la funcin fread.
El primer parmetro de fprintf es la direccin de la variable a escribir en disco, el segundo el tamao de bytes del dato que se va a escribir (devuelto por la funcin sizeof), el tercer parmetro es el nmero de datos que se van a escribir del tamao especificado (por lo comn ser 1) y el ltimo es el apuntador al archivo que se abri para escritura o modificacin.
Para tener datos de tamao fijo en los archivos y lo que formalmente sern 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 declaracin de un tipo struct se hace antes de la funcin main de la siguiente manera:
De este modo se crea una estructura de nombre DatosCliente con los campos descritos, en el programa se podrn declarar variables de tipo DatosCliente y para acceder a cada uno de los campos se utilizara la notacin registro.campo. La declaracin 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 lnea:
micliente.nombre
El uso de una estructura y de las funciones fread, fwrite y fseek ser bsicamente la diferencia entre programar para utilizar un archivo secuencial y un archivo de acceso directo. Cmo 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; };
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; }
Cmo escribir y leer datos de un archivo de acceso directo La introduccin de los datos ser mediante la misma funcin fwrite, donde lo que se escribe es la variable del tipo de la estructura deseada, con el tamao de la misma estructura y el apuntador al archivo. Cada dato debe ser llenado con scanf al campo deseado de la misma estructura. A continuacin 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 funcin fread, cuyos parmetros son: la variable que almacena los datos ledos del archivo, el tamao de la estructura o del tipo de dato, el nmero 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; }