Archivos en lenguaje C

Anuncio
Archivos en lenguaje C Los archivos, a diferencia de las estructuras de datos conocidas hasta ahora (variables simples, arreglos) son estructuras de datos almacenadas de manera permanente (discos rígidos, DVDs, pendrives, etc.). Poseen un nombre y una extensión, y se encuentra en un directorio. Cuando un programa termina su ejecución el contenido de las variables definidas en memoria se pierde. Pero si esos datos son guardados en un archivo, estarán disponibles la próxima vez que el programa se ejecute. Generalidades Para guardar o recuperar información de un archivo es necesario realizar una serie de operaciones. El formato de la declaración de un archivo es el siguiente: FILE* arch; donde: ● FILE* contendrá la información necesaria para poder procesar el archivo deseado, ● la variable archrepresentará
al archivo durante toda la ejecución del programa, hasta que el archivo sea cerrado. Antes de usar un archivo es necesario realizar una operación de apertura del mismo. Si se desea almacenar datos en él habrá que realizar una operación de escritura y si se desea leer datos de él habrá que hacer una operación de lectura. Cuando ya no se quiera utilizar el archivo se deberá realizar una operación de cierre. La función utilizada para abrir un archivo es: arch = fopen(nombre_del_archivo, modo_de_apertura); Si existiese algún tipo de error al realizar esta operación la función fopendevuelve
el valor NULL. La forma habitual de utilizar la instrucción fopenes
dentro de una sentencia condicional que permita conocer si se ha producido o no error en la apertura, por ejemplo: FILE *arch; if ((arch = fopen("datos.txt", "r")) == NULL) { /* control del error de apertura */ printf("Error en la apertura.\n"); } El modo de apertura es una string que indica el uso que se va ha hacer del archivo (lectura, escritura, etc.). Se debe indicar: ● si se desea abrir el archivo para lectura (“r”), para escritura (“w”) o para agregarle datos (“a”) ● si se trata de un archivo binario (“b”) o de texto ● si se desea actualizar el archivo (“+”) Realizando combinaciones se pueden obtener distintos modos de apertura, con características particulares: Si el archivo existe... Si el archivo no existe... r Lo abre para lectura Devuelve un error (NULL) w Lo abre para escritura, descartando el Lo crea y lo abre para escritura contenido previo a Lo abre para agregar datos al final r+ Lo abre para lectura y escritura Lo crea y lo abre para agregar datos al final Devuelve un error w+ Lo abre para escritura y lectura, Lo crea y lo abre para escritura y lectura descartando el contenido previo a+ Lo abre para agregar datos al final y Lo crea y lo abre para agregar datos al lectura final y lectura Cuando se termine el tratamiento del archivo hay que cerrarlo. La función utilizada para esto es: fclose(arch); Finalmente, una función muy útil es la que permite detectar cuándo se llegó al final del archivo que se está procesando. Esto ocurre cuando en lugar de realizar una lectura válida, se lee lo que se llama “marca de fin de archivo”, ubicada por detrás del último byte del archivo. Esta función es: feof(arch); La función feofdevuelve
VERDADEROen
caso de haber llegado al final del archivo; si no, devuelve FALSO. Esta función es muy utilizada en una estrategia frecuente para realizar la lectura secuencial de un archivo: // abrir archivo // leer archivo while (!feof(arch)) { // realizar operaciones varias // leer archivo } // cerrar archivo Esto se debe a que es necesario realizar una lectura adicional para poder detectar la marca de fin de archivo y así detener el recorrido del archivo. Las funciones de manejo de archivos mencionadas se encuentran en la biblioteca <stdio.h> Operaciones de lectura y escritura en archivos de texto Un archivo de texto está constituído por líneas de caracteres de distinto tamaño terminadas en un retorno de carro o enter (‘\n’). Se los denomina archivos de acceso secuencial, ya que para leer un carácter en particular se deben leer todos los caracteres anteriores al mismo. Existen distintas formas de leer y escribir archivos de texto: ● de a un carácter por vez ● de a una línea completa por vez ● utilizando un formato determinado Las funciones son las siguientes: Lectura Escritura De a un carácter int fgetc(FILE *archivo) int fputc(char caracter, FILE *archivo) De a una línea char * fgets(char *cadena, int tamaño, FILE *archivo) int fputs(char *cadena, FILE *archivo) Con formato int fscanf(FILE *archivo, char *formato, ...) int fprintf(FILE *archivo, char *formato, ...) Operaciones carácter a carácter La función fgetcpermite
leer un carácter de un archivo, devolviendo el carácter leído o la constante EOF, de acuerdo a si la lectura fue exitosa o no. Si bien hablamos de caracteres, el valor de retorno es SIEMPRE un int, por lo que debe ser igualado a una variable de este tipo. Si la lectura fuera exitosa, el intcontiene
el código ASCIIdel
carácter leído y puede copiarse a una variable de tipo char. Si la lectura no fuera exitosa, contiene el valor EOF. Sólo se debe copiar el valor leído a una variable de de tipo char luego se asegurar que no sea EOF. La función fputcpermite
guardar un carácter en un archivo, devolviendo el carácter escrito si la escritura fue exitosa, o EOF si no lo fue. Ejemplo: “Escribir un programa que copie todo el contenido del archivo de texto entrada.txt en el archivo de texto salida.txt, de a un carácter por vez” #include <stdio.h> int main() { FILE *fin, *fout; int aux; char car, ret; if (((fin = fopen("entrada.txt", "r")) == NULL) || ((fout = fopen("salida.txt" , "w")) == NULL)) { if (fout != NULL) fclose(fout); if (fin != NULL) fclose(fin); printf ("Error en la apertura.\n"); return ­1; } aux = fgetc(fin); while (!feof(fin)) { car = aux; // copio el int a un char porque no es EOF ret = fputc(car, fout); if (ret == EOF) printf ("Error de escritura.\n"); aux = fgetc(fin); } fclose(fin); fclose(fout); return 0; } Operaciones línea a línea La función fgetspermite
leer una cadena de caracteres de un archivo de a una vez, devolviendo la cadena de caracteres leída o NULL, de acuerdo a si la lectura fue exitosa o no. Con fgetsse
necesita especificar un arreglo de caracteres en donde se guardará lo leído desde el archivo, el tamaño de dicho arreglo y sobre qué archivo se va a estar trabajando. Esta función lee una línea completa hasta encontrar el ‘\n’(que
también copia a la cadena), o hasta tamaño­1caracteres,
agregando un ‘\0’al
final de la cadena. En caso de que no se termine de leer la línea, se seguirá leyendo tamaño­1caracteres
hasta llegar a su fin. La función fputspermite
escribir una cadena de caracteres en un archivo, devolviendo un valor entero positivo o EOF, de acuerdo a si la escritura fue exitosa o no. No escribe en el archivo el ‘\0’ni
agrega un ‘\n’al
final de la línea escrita. De requerirlo, hay que agregarlo manualmente. Ejemplo: “Escribir un programa que copie todo el contenido del archivo de texto entrada.txt en el archivo de texto salida.txt, de a una línea por vez” #include <stdio.h> int main() { FILE *fin, *fout; char cadena[100]; int ret; if (((fin = fopen("entrada.txt", "r")) == NULL) || ((fout = fopen("salida.txt" , "w")) == NULL)) { if (fout != NULL) fclose(fout); if (fin != NULL) fclose(fin); printf ("Error en la apertura.\n"); return ­1; } fgets(cadena, 100, fin); while (!feof(fin)) { ret = fputs(cadena, fout); if (ret == EOF) printf ("Error de escritura.\n"); fgets(cadena, 100, fin); } fclose(fin); fclose(fout); return 0; } Operaciones con formato La función fscanfpermite
leer un archivo con un formato determinado, convirtiendo los caracteres leídos en variables de tipos específicos, devolviendo la cantidad de variables asignadas o EOF, de acuerdo a si la lectura fue exitosa o no. Se utiliza de manera similar a scanf, con la diferencia de que la lectura se realiza sobre un archivo y no desde el teclado. Por ejemplo, si se tiene un archivo de texto que contiene la siguiente línea: 25 x litro\n podríamos definir tres variables: int numero; char caracter; char cadena[10]; y leer la línea completa de la siguiente manera: fscanf(arch, “%d %c %s\n”, &numero, &caracter, cadena); La función fscanfreconocerá
el formato de la línea comparándolo con el segundo parámetro recibido y: ● leerá los caracteres ‘2’y
‘5’y
los convertirá en el número 25, guardándolo en la variable numero; ● leerá el carácter ‘x’ y lo guardará en la variable caracter; ● leerá los caracteres ‘l’, ‘i’, ‘t’, ‘r’y
‘o’y
los guardará en el arreglo de caracteres cadena, guardando también un ‘\0’ al final del mismo. Cuando se realiza una lectura con fscanfhay
que tener en cuenta que considera a los espacios como separadores por defecto. Es por esta razón que, si durante la lectura de una cadena de caracteres (%s)encuentra
un espacio, una serie de espacios o un ‘\n’ la lectura terminará, por lo que no sirve para leer, por ejemplo, frases enteras compuestas por varias palabras separadas con espacios. La función fprintfpermite
escribir en un archivo un texto con formato, devolviendo la cantidad de caracteres escritos o un valor negativo, de acuerdo a si la escritura fue exitosa o no. Se utiliza de manera similar a printf, con la diferencia de que la escritura se realiza sobre un archivo y no en la pantalla. Siguiendo con el ejemplo anterior, si se quisiera escribir la línea 25 x litro\n, se debería llamar a la función fprintf de la siguiente manera: fprintf(arch, “%d %c %s\n”, numero, caracter, cadena); Ejemplo: “Escribir un programa que lea el archivo entrada.txt, que contiene las temperaturas mínimas y máximas de cada mes, y escriba el archivo salida.txt, que contendrá el promedio de las temperaturas extremo de cada mes. Cada línea del archivo entrada.txt contiene el mes del año, la temperatura mínima y la temperatura máxima del mismo, cada dato separado por un espacio. Cada línea del archivo salida.txt contendrá el mes de año y el promedio de temperaturas, ambos separados por un espacio.” #include <stdio.h> int main () { FILE *fin, *fout; char mes[15]; int tmin = 0, tmax = 0, ret; double promedio = 0; if (((fin = fopen("entrada.txt", "r")) == NULL) || ((fout = fopen("salida.txt" , "w")) == NULL)) { if (fout != NULL) fclose(fout); if (fin != NULL) fclose(fin); printf ("Error en la apertura.\n"); return ­1; } fscanf(fin,"%s %d %d", mes, &tmin, &tmax); while (!feof(fin)) { promedio = (tmin + tmax) / 2.0; ret = fprintf(fout, "%s %.1lf\n", mes, promedio); if (ret < 0) printf ("Error de escritura.\n"); fscanf(fin,"%s %d %d", mes, &tmin, &tmax); } fclose(fin); fclose(fout); return 0; } 
Descargar