archivos en lenguaje C

20
Introducción Índice A. Archivos secuenciales A.1. Definición A.2. Apertura y cierre A.3. Creación A.4. Leer dato A.5. Escribir los datos A.6. Ejemplos B. Archivos Aleatorio B.1. Definición B.2. Apertura y cierre B.3. Leer datos B.4. Escribir datos B.5. Funciones de entrada/salida B.6. Ejemplo programa

description

manejos de los archivos en programación en el lenguaje C.

Transcript of archivos en lenguaje C

Introduccin

ndice

A. Archivos secuenciales A.1. DefinicinA.2. Apertura y cierreA.3. CreacinA.4. Leer datoA.5. Escribir los datosA.6. Ejemplos

B. Archivos AleatorioB.1. DefinicinB.2. Apertura y cierreB.3. Leer datosB.4. Escribir datosB.5. Funciones de entrada/salidaB.6. Ejemplo programa

A. Archivos secuenciales

1. Definicin

R: Es la forma bsica de organizar un conjunto de registros, que forman un archivo, utilizando una organizacin secuencial. En un archivo organizado secuencialmente, lo registros quedan grabados consecutivamente cuando el archivo se utiliza como entrada. En la mayora de los casos, los registros de un archivo secuencial quedan ordenados de acuerdo con el valor de algn campo de cada registro. Semejante archivo se dice que es un archivo ordenado; el campo, o los campos, cuyo valor se utiliza para determinar el ordenamiento es conocido como la llave del ordenamiento. Un archivo puede ordenarse ascendente o descendentemente con base en su llave de ordenamiento. La forma ms comn de estructura de archivo es el archivo secuencial. En este tipo de archivo, un formato fijo es usado para los registros. Todos los registros tienen el mismo tamao, constan del mismo nmero de campos de tamao fijo en un orden particular. Como se conocen la longitud y la posicin de cada campo, solamente los valores de los campos se necesitan almacenarse; el nombre del campo y longitud de cada campo son atributos de la estructura de archivos. 2. Apertura y cierre:Abrir:Usar un archivo desde un programa en C, tanto secuencial como directo, lo primero que hay que hacer es abrirlo. Esto crea un flujo que conecta nuestro programa con el archivo.La funcin para abrir archivos es fopen(), que tiene esta sintaxis:FILE *fopen(char *nombre_archivo, char *modo);Cierre:Cuando un archivo no va a usarse ms, su flujo debe ser cerrado para liberar memoria. Aunque tericamente todos los archivos abiertos por un programa se cierran automticamente al finalizar dicho programa, el programador, por precaucin, debe ocuparse de hacerlo dentro del cdigo.Para cerrar un archivo se usa la funcin fclose(), con esta sintaxis:int fclose(FILE* puntero_file);

Fin de fichero: feof()

EOF es una constante definida en stdio.h. La funcin feof(), nos dice si hemos alcanzado el final de un archivo. Devuelve un 0 (falso) si an no se ha llegado al final, y otro valor cuando se ha alcanzado. Es muy til para saber si podemos seguir leyendo caracteres o ya los hemos ledo todos. Su prototipo es:int feof(FILE* puntero_a_archivo);fscanf():Lee los datos de un archivo, en lugar de hacerlo del flujo stdin (es decir, del teclado).Los modos de apertura vlidos son: Modo r: Abre el archivo existente para lectura en modo secuencial. El archivo debe existir previamente. Modo w: Crea un archivo nuevo para escritura en modo secuencial. Cuidado! Si el archivo ya existe, se borrar y se crear uno nuevo. Modo a: Abre un archivo existente para escritura en modo secuencial, aadiendo los datos al final de los que haya. Si el archivo no existe, secrea. Modo r+: Abre el archivo para lectura/escritura en modo directo. El archivo debe existir previamente. Se puede leer y escribir en cualquier posicin del archivo. Modo w+: Crea un archivo para lectura/escritura en modo directo. Si el archivo ya existe, se elimina y se crea de nuevo. Se puede leer y escribir en cualquier posicin del archivo. Modo a+: Abre un archivo existente para lectura/escritura en modo directo. Si el archivo no existe, lo crea. La escritura slo se podr realizar al final del archivo (modo aadir), aunque se puede leer en cualquier posicin.A todos estos modos se les puede aadir la letra b si el archivo es binario, o t si es de texto.

3. Creacin de archivos secuenciales.

La creacin de un archivo secuencial se realiza agregando registros al final del archivo, no importa el medio de entrada de datos. El archivo secuencial puede ser almacenado en cintas o en discos magnticos. Un archivo secuencial puede tener registros fijos o variables, la declaracin del archivo y la definicin del registro depender del lenguaje de programacin que se vaya a usar.Un archivo secuencial se puede crear de dos forma distintas. Una es crear el archivo directamente, usando un procesador de texto o un editor. La otra forma es escribir el programa que introduzca informacin en las computadoras y la escriba en un archivo. Los archivos sin formatos solo se pueden crearse con programas especialmente escritos para tal fin.

4. Leer datos:Los archivos datos que contienen solo cadenas de cadena de caracteres pueden crearse y leerse ms fcilmente con programas que utilizan funciones de la biblioteca especialmente orientados para cadena de caracteres. Algunas funciones de este tipo son gets, puts, fgets, fputs, las dos primeras leen o escriben cadenas de caracteres desde dispositivos de salidas, mientras que las otras las intercambias por archivos. 5. Escritura de los archivos secuenciales:

En estos archivos, la informacin slo puede leerse y escribirse empezando desde el principio del archivo.

Los archivos secuenciales tienen algunas caractersticas que hay que tener en cuenta:

1. La escritura de nuevos datos siempre se hace al final del archivo.2. Para leer un dato concreto del archivo hay que avanzar siempre hasta donde se encuentre dicho dato. Si el dato requerido se encuentra antes del dato en que est se est posicionado el archivo en un momento dado, ser necesario regresar al comienzo del archivo y avanzar hasta el dato necesario.

Escribir datos en un archivo

Para escribir datos a un archivo se utilizan las instrucciones Write y WriteLn, como si se quisiera escribir a la pantalla, con la diferencia de que se especificar la variable de archivo ya declarada. Ejemplo:

WriteLn(VarArchivo, 'Prueba de archivos'); Esta sentencia grabara el texto 'Prueba de archivos' en el archivo asignado a VarArchivo.

6. Programa ejemplo de archivo secuencial#include #include 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;}

B. Archivos Aleatorios

1 Definicin:Es aquel en donde los datos se guardan en registros mediante una estructura definida de tipo Type.Los archivos de acceso aleatorio son ms verstiles, permiten acceder a cualquier parte del fichero en cualquier momento, como si fueran arrays en memoria.Las operaciones de lectura y/o escritura pueden hacerse en cualquier punto del archivo.

2 Apertura de un archivo aleatorio

Para procesar un archivo en C la primera operacin que hay que realizar es abrir el archivo. La apertura del archivo supone conectar el archivo externo con el programa, e indicar cmo va a ser tratado el archivo: binario, de caracteres, etc. El programa accede a los archivos a travs de un puntero a la estructura FILE, la funcin de apertura devuelve dicho puntero. La funcin para abrir un archivo es fopen() y el formato de llamada es: fopen(nombre_archivo, modo);

Donde nombre_archivo es un puntero a una cadena de caracteres que representan un nombre vlido del archivo y puede incluir una especificacin del directorio. La cadena a la que apunta modo determina como se abre el archivo. La funcin devuelve un puntero a FILE, a travs de dicho puntero el programa hace referencia al archivo. La llamada fopen() se debe hacer de tal forma que el valor que devuelve se asigne a una variable puntero a FILE, para as despus referirse a dicha variable. El siguiente ejemplo declara una variable de tipo puntero a FILE y posteriormente se utiliza una sentencia se apertura de archivo. FILE* pf;pf = fopen(nombre_archivo, modo); A continuacin se muestra una tabla conteniendo los modos permitidos para abrir un archivo as como su significado. ModoSignificadorAbre un archivo de texto para lectura.wCrea un archivo de texto para escritura.aAbre un archivo de texto para aadir.rbAbre un archivo binario para lectura.wbCrea un archivo binario para escritura.abAbre un archivo binario para aadir.r+Abre un archivo de texto para lectura / escritura.w+Crea un archivo de texto para lectura / escritura.a+Aade o crea un archivo de texto para lectura / escritura.r+bAbre un archivo binario para lectura / escritura.w+bCrea un archivo binario para lectura / escritura.a+bAade o crea un archivo binario para lectura / escritura.

Cierre de un archivo aleatorio

La funcin fclose() cierra una secuencia que fue abierta mediante una llamada a fopen(). Escribe toda la informacin que todava se encuentre en el buffer en el disco 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 prdida de datos, destruccin de archivos y posibles errores intermitentes en el programa. El prototipo de esta funcin es:

int fclose(FILE *F);

Donde F es el puntero al archivo devuelto por la llamada a fopen(). Si se devuelve un valor cero significa que la operacin de cierre ha tenido xito si ha habido algn error, el valor de retorno es la constante EOF.

3Lectura de datos

fgetcEsta funcin lee un caracter a la vez del archivo que esta siendo sealado con el puntero *archivo. En caso de que la lectura sea exitosa devuelve el caracter ledo y en caso de que no lo sea o de encontrar el final del archivo devuelve EOF.El prototipo correspondiente de fgetc es:

char fgetc(FILE *archivo);

Esta funcin se usa generalmente para recorrer archivos de texto.

fgetsEsta funcin est diseada para leer cadenas de caracteres. Leer hasta n-1 caracteres o hasta que lea un cambio de lnea '\n' o un final de archivo EOF. En este ltimo caso, el carcter de cambio de lnea '\n' tambin es ledo.El prototipo correspondiente de fgets es:

char *fgets(char *buffer, int tamao, FILE *archivo);

El primer parmetro buffer lo hemos llamado as porque es un puntero a un espacio de memoria del tipo char (podramos usar un arreglo de char). El segundo parmetro es tamao que es el limite en cantidad de caracteres a leer para la funcion fgets. Y por ultimo el puntero del archivo por supuesto que es la forma en que fgets sabra a que archivo debe leer.

freadsize_t fread ( void * ptr, size_t size, size_t count, FILE * stream );Esta funcin lee un bloque de una "stream" de datos. Efecta la lectura de un arreglo de elementos "count", cada uno de los cuales tiene un tamao definido por "size". Luego los guarda en el bloque de memoria especificado por "ptr". El indicador de posicin de la cadena de caracteres avanza hasta leer la totalidad de bytes. Si esto es exitoso la cantidad de bytes ledos es (size*count).

PARAMETROS:ptr : Puntero a un bloque de memoria con un tamao mnimo de (size*count) bytes.size : Tamao en bytes de cada elemento (de los que voy a leer).count : Nmero de elementos, los cuales tienen un tamao "size".stream: Puntero a objetos FILE, que especifica la cadena de entrada.

fscanfLa funcin fscanf funciona igual que scanf en cuanto a parmetros, pero la entrada se toma de un fichero en lugar del teclado.El prototipo correspondiente de fscanf es:

int fscanf(FILE *fichero, const char *formato, argumento, ...);

4.Escritura de datos

fputcEsta funcin escribe un carcter a la vez del archivo que esta siendo sealado con el puntero *archivo. El valor de retorno es el carcter escrito, si la operacin fue completada con xito, en caso contrario ser EOF.El prototipo correspondiente de fputc es:

int fputc(int carcter, FILE *archivo);

fputsLa funcin fputs escribe una cadena en un fichero. No se aade el carcter de retorno de lnea ni el carcter nulo final. El valor de retorno es un nmero no negativo o EOF en caso de error. Los parmetros de entrada son la cadena a escribir y un puntero a la estructura FILE del fichero donde se realizar la escritura.El prototipo correspondiente de fputs es:

int fputs(const char *buffer, FILE *archivo);

fwriteEsta funcin est pensada para trabajar con registros de longitud constante y forma pareja con fread. Es capaz de escribir hacia un fichero uno o varios registros de la misma longitud almacenados a partir de una direccin de memoria determinada. El valor de retorno es el nmero de registros escritos, no el nmero de bytes. Los parmetros son: un puntero a la zona de memoria de donde se obtendrn los datos a escribir, el tamao de cada registro, el nmero de registros a escribir y un puntero a la estructura FILE del fichero al que se har la escritura.El prototipo correspondiente de fwrite es:size_t fwrite(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);fprintfLa funcin fprintf funciona igual que printf en cuanto a parmetros, pero la salida se dirige a un archivo en lugar de a la pantalla.El prototipo correspondiente de fprintf es:

int fprintf(FILE *archivo, const char *formato, argumento, ...);

5. Funciones para la lectura y escritura de cadenas en archivosY ejemplos de programas. Funcin fgets: Esta funcin est diseada para leer cadenas de caracteres. Leer hasta n-1 caracteres o hasta que lea un retorno de lnea. En este ltimo caso, el carcter de retorno de lnea tambin es ledo. El parmetro n nos permite limitar la lectura para evitar desbordar el espacio disponible en la cadena. El valor de retorno es un puntero a la cadena leda, si se ley con xito, y es NULL si se detecta el final del archivo o si hay un error. Los parmetros son: la cadena a leer, el nmero de caracteres mximo a leer y un puntero a una estructura FILE del arcvhivo del que se leer. Sintxis: char *fgets(char *cadena, int n, FILE *fichero); Funcin fputs: La funcin fputs escribe una cadena en un archivo. No se aade el carcter de retorno de lnea ni el carcter nulo final. El valor de retorno es un nmero no negativo o EOF en caso de error. Los parmetros de entrada son la cadena a escribir y un puntero a la estructura FILE del archivo donde se realizar la escritura. Sintxis:int fputs(const char *cadena, FILE *stream);

Funciones para la lectura y escritura en registros de longitud fija Funcin fread: Esta funcin est pensada para trabajar con registros de longitud constante. Es capaz de leer desde un archivo uno o varios registros de la misma longitud y a partir de una direccin de memoria determinada. El usuario es responsable de asegurarse de que hay espacio suficiente para contener la informacin leda. El valor de retorno es el nmero de registros ledos, no el nmero de bytes. Los parmetros son: un puntero a la zona de memoria donde se almacenarn los datos ledos, el tamao de cada registro, el nmero de registros a leer y un puntero a la estructura FILE del fichero del que se har la lectura. Sintxis: size_t fread(void *puntero, size_t tamao, size_t nregistros, FILE *fichero); Funcin fwrite: Esta funcin tambin est pensada para trabajar con registros de longitud constante y forma pareja con fread. Es capaz de escribir hacia un archivo uno o varios registros de la misma longitud almacenados a partir de una direccin de memoria determinada. El valor de retorno es el nmero de registros escritos, no el nmero de bytes. Los parmetros son: un puntero a la zona de memoria donde se almacenarn los datos ledos, el tamao de cada registro, el nmero de registros a leer y un puntero a la estructura FILE del fichero del que se har la lectura. Sintxis: size_t fwrite(void *puntero, size_t tamao, size_t nregistros, FILE *fichero); Funciones 'c' especficas para archivos de acceso aleatorio Funcin fseek: Esta funcin sirve para situar el cursor del archivo para leer o escribir en el lugar deseado. El valor de retorno es cero si la funcin tuvo xito, y un valor distinto de cero si hubo algn error. Los parmetros de entrada son: un puntero a una estructura FILE del fichero en el que queremos cambiar el cursor de lectura/escritura, el valor del desplazamiento y el punto de origen desde el que se calcular el desplazamiento. El parmetro origen puede tener tres posibles valores:oSEEK_SET: el desplazamiento se cuenta desde el principio del fichero. El primer byte del fichero tiene un desplazamiento cero. oSEEK_CUR: el desplazamiento se cuenta desde la posicin actual del cursor. oSEEK_END: el desplazamiento se cuenta desde el final del fichero. Sintaxis: int fseek(FILE *fichero, long int desplazamiento, int origen); Funcin ftell: La funcin ftell sirve para averiguar la posicin actual del cursor de lectura/excritura de un archivo. El valor de retorno ser esa posicin, o -1 si hay algn error. El parmetro de entrada es un puntero a una estructura FILE del fichero del que queremos leer la posicin del cursor de lectura/escritura. Sintaxis: long int ftell(FILE *fichero);

6. programa ejemplo

#include #include struct stRegistro { char valido; // Campo que indica si el registro es vlido S->Vlido, N->Invlido char nombre[34]; int dato[4];};

int Menu();void Leer(struct stRegistro *reg);void Mostrar(struct stRegistro *reg);void Listar(long n, struct stRegistro *reg);long LeeNumero();void Empaquetar(FILE **fa); int main(){ struct stRegistro reg; FILE *fa; int opcion; long numero; fa = fopen("alea.dat", "r+b"); // Este modo permite leer y escribir if(!fa) fa = fopen("alea.dat", "w+b"); // si el fichero no existe, lo crea. do { opcion = Menu(); switch(opcion) { case '1': // Aadir registro Leer(&reg); // Insertar al final: fseek(fa, 0, SEEK_END); fwrite(&reg, sizeof(struct stRegistro), 1, fa); break; case '2': // Mostrar registro system("cls"); printf("Mostrar registro: "); numero = LeeNumero(); fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET); fread(&reg, sizeof(struct stRegistro), 1, fa); Mostrar(&reg); break; case '3': // Eliminar registro system("cls"); printf("Eliminar registro: "); numero = LeeNumero(); fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET); fread(&reg, sizeof(struct stRegistro), 1, fa); reg.valido = 'N'; fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET); fwrite(&reg, sizeof(struct stRegistro), 1, fa); break; case '4': // Mostrar todo rewind(fa); numero = 0; system("cls"); printf("Nombre Datos\n"); while(fread(&reg, sizeof(struct stRegistro), 1, fa)) Listar(numero++, &reg); system("PAUSE"); break; case '5': // Eliminar marcados Empaquetar(&fa); break; } } while(opcion != '0'); fclose(fa); return 0;} // Muestra un men con las opciones disponibles y captura una opcin del usuarioint Menu(){ char resp[20]; do { system("cls"); printf("MENU PRINCIPAL\n"); printf("--------------\n\n"); printf("1- Insertar registro\n"); printf("2- Mostrar registro\n"); printf("3- Eliminar registro\n"); printf("4- Mostrar todo\n"); printf("5- Eliminar registros marcados\n"); printf("0- Salir\n"); fgets(resp, 20, stdin); } while(resp[0] < '0' && resp[0] > '5'); return resp[0];} // Permite que el usuario introduzca un registro por pantallavoid Leer(struct stRegistro *reg){ int i; char numero[6]; system("cls"); printf("Leer registro:\n\n"); reg->valido = 'S'; printf("Nombre: "); fgets(reg->nombre, 34, stdin); // la funcin fgets captura el retorno de lnea, hay que eliminarlo: for(i = strlen(reg->nombre)-1; i && reg->nombre[i] < ' '; i--) reg->nombre[i] = 0; for(i = 0; i < 4; i++) { printf("Dato[%1d]: ", i); fgets(numero, 6, stdin); reg->dato[i] = atoi(numero); }} // Muestra un registro en pantalla, si no est marcado como borradovoid Mostrar(struct stRegistro *reg){ int i; system("cls"); if(reg->valido == 'S') { printf("Nombre: %s\n", reg->nombre); for(i = 0; i < 4; i++) printf("Dato[%1d]: %d\n", i, reg->dato[i]); } system("PAUSE");} // Muestra un registro por pantalla en forma de listado,// si no est marcado como borradovoid Listar(long n, struct stRegistro *reg){ int i; if(reg->valido == 'S') { printf("[%6ld] %-34s", n, reg->nombre); for(i = 0; i < 4; i++) printf(", %4d", reg->dato[i]); printf("\n"); }} // Lee un nmero suministrado por el usuariolong LeeNumero(){ char numero[6]; fgets(numero, 6, stdin); return atoi(numero);} // Elimina los registros marcados como borradosvoid Empaquetar(FILE **fa){ FILE *ftemp; struct stRegistro reg;

ftemp = fopen("alea.tmp", "wb"); rewind(*fa); while(fread(&reg, sizeof(struct stRegistro), 1, *fa)) if(reg.valido == 'S') fwrite(&reg, sizeof(struct stRegistro), 1, ftemp); fclose(ftemp); fclose(*fa); remove("alea.bak"); rename("alea.dat", "alea.bak"); rename("alea.tmp", "alea.dat"); *fa = fopen("alea.dat", "r+b");

Conclusin