FICHEROS Lenguajes de programación LPSI EUI UPM • Secuencia de bytes • Estructura dependiente de la escritura y lectura de la información • Manejo como: – Binarios: se tratan bytes – Texto: se tratan caracteres • Fichero de disco asociado en el programa a una vble, con la que se maneja, de tipo FILE * • Tipo FILE definido en stdio.h. Es una estructura conteniendo información del fichero y el buffer asociado Lenguajes de programación LPSI EUI UPM • Buffer asociado a cada fichero al abrirlo • Lecturas de datos del disco al buffer, de donde los va leyendo el programa • Escrituras de datos al buffer, cuando se llena éste se envían al disco • Lecturas y escrituras sobre el disco del tamaño del buffer • EOF constante asociada al fin de fichero. Valor -1. Definida en stdio.h • Declaración FILE * nom_vble; Lenguajes de programación LPSI EUI UPM • Ficheros estándar: – stdin: entrada estándar (teclado) – stdout: salida estándar (pantalla) – stderr: fichero de errores estándar Lenguajes de programación LPSI EUI UPM APERTURA DE FICHEROS FILE * fopen (const char * nom_fich, const char * modo) nom_fich: nombre del fichero en disco o camino completo para llegar a él modo: forma de apertura Devuelve: – NULL en caso de fallo en la apertura – Un puntero a una estructura FILE asociada a partir de ese momento al fichero Lenguajes de programación LPSI EUI UPM APERTURA DE FICHEROS • Modos válidos: “r” lectura (abre) “w” escritura (crea o vacía) “a” añadir al final (abre o crea) “rb” “wb” “ab” lectura (abre) escritura (crea o vacía) añadir al final (abre o crea) TEXTO BINARIOS Lenguajes de programación LPSI EUI UPM APERTURA DE FICHEROS • Modos de actualización: “r+” lectura (abre) “w+” escritura (crea o vacía) “a+” añadir al final (abre o crea) “rb+” lectura (abre) “wb+” escritura (crea o vacía) “ab+” añadir al final (abre o crea) TEXTO BINARIOS Lenguajes de programación LPSI EUI UPM APERTURA DE FICHEROS • Es posible también “r+b”, “w+b” y “a+b” • En actualización, una lectura no puede ir seguida de una lectura, o viceversa, si previamente no se ha hecho un posicionamiento sobre el fichero con: fflush, fseek, fgetpos o rewind • Ejemplo: FILE * f_in, * f_out; f_in = fopen (“datos.dat”, “rb”); f_out = fopen (“c:salida.txt”, “w”); Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS int fclose (FILE *) • Cierra el fichero pasado como parámetro • Elimina la vble asociada • Si es de escritura, graba el contenido del buffer en el disco • Devuelve: –0 si no error – EOF si error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS int fflush (FILE *) • Vacía el buffer asociado al fichero pasado como parámetro • Si es de escritura, se graba el contenido del buffer en disco • Si es de lectura, se elimina el contenido del buffer • fflush() vacía los buffers de todos los ficheros abiertos en ese momento Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS int feof (FILE *) • Indica si se ha alcanzado el fin de fichero • Devuelve: – <> 0 –0 si es fin de fichero si no es fin de fichero Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS int rewind (FILE *) • Fija la posición del fichero al principio del mismo int remove (const char * nombre) • Borra del disco el fichero especificado • Devuelve: – <>0 –0 si error si no error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS int rename (const char * nom_antig, const char * nom_nuevo) • Cambia el nombre de un fichero de disco • Devuelve: – <> 0 –0 si error si no error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS FILE * freopen (const char *nombre, const char * modo, FILE * f) • Acciones: 1. Cierra el fichero asociado a f 2. Abre el fichero de disco con el nombre indicado y lo asocia a la vble f 3. Devuelve: - NULL si error Una estructura FILE si no error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS BINARIOS unsigned fwrite (void * vble, unsigned tam, unsigned n_elem, FILE * f) • Escribe n_elem, de tam bytes cada uno, que están en memoria a partir de la posición indicada por vble, en el fichero asociado a f • Devuelve el nº de elementos escritos Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS BINARIOS unsigned fread (void * vble, unsigned tam, unsigned n_elem, FILE * f) • Lee n_elem, de tam bytes cada uno, que están en el buffer del fichero asociado a f, y los deja en la zona de memoria apuntada por vble • Devuelve el nº de elementos leídos Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS BINARIOS int fseek (FILE *f, long desplaz, int origen) • Con ficheros abiertos para actualización • Establece la posición actual del fichero para leer o escribir • Desplaz: nº de bytes que se moverá la posición actual a partir del origen • Origen: – SEEK_SET principio de fichero – SEEK_END fin de fichero – SEEK_CUR posición actual • En ficheros de texto, obligatoriamente: – Desplaz = 0 ó valor devuelto por ftell – Origen = SEEK_SET • Devuelve: – <> 0 si error – 0 si no error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS BINARIOS long ftell (FILE *) • Devuelve: – la posición actual del fichero pasado como parámetro – -1 si error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS BINARIOS int fgetpos (FILE * f, unsigned long * pos) • Guarda en pos la posición actual del fichero pasado como parámetro • Devuelve: – <> 0 –0 si error si no error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS BINARIOS int fsetpos (FILE *f, unsigned long * pos) • Sitúa la posición actual del fichero pasado como parámetro en el byte indicado por pos, que se tiene que haber obtenido mediante fgetpos • Devuelve: – <> 0 –0 si error si no error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS TEXTO int fprintf (FILE * f, const char * formato, …) • Igual que printf, pero los resultados se imprimen sobre el fichero de texto pasado como parámetro • Devuelve – El número de caracteres escritos – <0 si error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS TEXTO int fscanf (FILE *f, const char * formato, …) • Igual que scanf, pero lee los valores del fichero de texto pasado como parámetro • Devuelve: – El número de elementos leídos – EOF si error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS TEXTO int fgetc (FILE *) • Devuelve: – el siguiente carácter del fichero pasado como parámetro – EOF si fin de fichero o error • fgetc (stdin) getchar() int getc (FILE *) * Igual que fgetc Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS TEXTO int fputc (int c, FILE * f) • Escribe el carácter c en el fichero de texto f • Devuelve: – El carácter escrito – EOF si error int putc (int c, FILE * f) * Igual a fputc Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS TEXTO char * fgets (char *cad, int n, FILE * f) • Lee, como máximo, n-1 caracteres del fichero de texto f y los deja en cad, añadiendo al final ‘\0’. Si encuentra un fin de línea o de fichero antes de leer los n-1 caracteres, no sigue leyendo • Devuelve: – La dirección de la cadena leída – NULL si encuentra el fin de fichero sin leer ningún carácter o error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS TEXTO int fputs (const char * cad, FILE *f) • Escribe el contenido de la cadena cad en el fichero de texto f, excepto el ‘\0’ • Devuelve: – >= 0 – EOF si no error si error Lenguajes de programación LPSI EUI UPM MANEJO DE FICHEROS TEXTO int ungetc (int c, FILE *f) • Almacena, al comienzo del buffer de lectura asociado al fichero f, el carácter c, que deberá ser distinto de EOF. La siguiente lectura leerá este carácter • Se pueden hacer varios ungetc seguidos sobre un fichero y se recuperarán en orden inverso a su reinserción, aunque no se garantiza el resultado • Devuelve: – El carácter reinsertado – EOF si error Lenguajes de programación LPSI EUI UPM EJEMPLOS • Escribir un programa que cuente el número de líneas contenidas en el fichero de texto “libro.txt”. Las líneas no exceden de 80 caracteres. main () { FILE * f_in; char linea [81]; unsigned conta = 0; Lenguajes de programación LPSI EUI UPM if (! (f_in = fopen (“libro.txt”, “r”))) { printf (“Error en la apertura del fichero\n”); printf (“Pulse una tecla para continuar…”); getch(); return(); } while (fgets (linea, 81, f_in)) conta ++; fclose (f_in); printf (“\nEl número total de líneas contenidas en el fichero es: %i.\n”, conta); } Lenguajes de programación LPSI EUI UPM • Escribir un programa que grabe en el fichero “alumnos.dat” la información de un conjunto de alumnos, conteniendo: nombre, apellidos, matrícula, domicilio, código postal y dni. typedef struct { char nombre[15], apellidos[40], matric[7], domic[50], cod_post[6], dni[10]; } T_ALUMNO; Lenguajes de programación LPSI EUI UPM main () { FILE * f_sal; T_ALUMNO alum; char respuesta; if (! (f_sal = fopen (“alumnos.dat”, “wb”))) { printf (“Error en la apertura del fichero.\n”); printf (“Pulse una tecla para continuar…”); getch(); } Lenguajes de programación LPSI EUI UPM do { printf (“\nIntroduzca el nombre: “); gets (alum.nombre); printf (“\nIntroduzca los apellidos: “); gets (alum.apellidos); printf (“\nIntroduzca nº de matrícula: “); gets (alum.matric); printf (“\nIntroduzca el domicilio: “); gets (alum.domic); printf (“\nIntroduzca el código postal: “); gets (alum.cod_post); printf (“\nIntroduzca el dni: “); gets (alum.dni); fwrite (&alum, sizeof(T_ALUMNO), 1, f_sal); printf (“\n\n\n ¿Nuevo alumno (s/n)?: “); respuesta = getchar (); fflush (stdin); } while (‘s’ == respuesta || ‘S’ == respuesta); fclose (f_sal); } Lenguajes de programación LPSI EUI UPM • Escribir un programa que lea círculos de un fichero cuyo nombre se lee de teclado, y grabe aquéllos cuyo centro esté en el primer cuadrante en un fichero con nombre “circulos.dat”, en el disquete. Cada círculo viene representado por centro y radio. typedef struct { int x, y;} T_PUNTO; typedef struct { T_PUNTO centro; unsigned radio; } T_CIRCULO; Lenguajes de programación LPSI EUI UPM main () { FILE * f_circ, f_sal; T_CIRCULO circ; char respuesta, nombre[25]; printf (“Introduzca el nombre del fichero de círculos: “); scanf (“%s”, nombre); if (! (f_circ = fopen(nombre, “rb”))) { printf (“Error en la apertura del fichero %s\n.”, nombre); printf (“Pulse una tecla para continuar…”); getch(); return(); } Lenguajes de programación LPSI EUI UPM if (! (f_sal = fopen (“a:circulos.dat”, “wb”))) { printf (“\nError en la apertura del fichero a:circulos.dat\n”); printf (“Pulse una tecla para continuar…”); getch(); fclose (f_circ); return(); } Lenguajes de programación LPSI EUI UPM while (fread (&circ, sizeof (T_CIRCULO), 1, f_circ)) if (circ.centro.x >= 0 && circ.centro.y >= 0) fwrite (&circ, sizeof (T_CIRCULO), 1, f_circ); fclose (f_circ); fclose (f_sal); } Lenguajes de programación LPSI EUI UPM • Escribir un programa que grabe en un fichero de texto líneas leídas por teclado. Se acabará cuando se hayan leído 200 líneas o se lea una cuyo primer carácter sea ‘*’. main () { FILE * f_sal; char linea[256]; unsigned conta = 0; Lenguajes de programación LPSI EUI UPM if (! (f_circ = fopen(nombre, “rb”))) { printf (“Error en la apertura del fichero %s\n.”, nombre); printf (“Pulse una tecla para continuar…”); getch(); return(); } printf (“Introduzca un máximo de 200 líneas de texto o introducir * al principio de línea para acabar.\n\n\n”); Lenguajes de programación LPSI EUI UPM gets(linea); while (conta < 200 && ‘*’ != linea[0]) { conta ++; fprintf (f_sal, “%s\n”, linea); } fclose (f_sal); } Lenguajes de programación LPSI EUI UPM ARGUMENTOS EN MAIN • Posibilidad de pasar argumentos a main desde la línea de comandos y devolver un resultado de la ejecución tipo main (int argc, char * argv[]) tipo: normalmente int (0 ejecución normal, <>0 algún código de error) argc: nº de elementos en la línea de comando, incluido el nombre del programa. Hay que controlar el nº de argumentos en la llamada argv: array de cadenas, cada una conteniendo uno de los argumentos de la línea de comandos Lenguajes de programación LPSI EUI UPM c:\copy a:texto.txt d: argc = 3 argv = “copy” “a:texto.txt” “d:” • Terminación de main: – Return (valor). Devuelve el control a la función llamante, en este caso acaba la ejecución – Exit (valor). Termina la ejecución del programa y devuelve el código. Lenguajes de programación LPSI EUI UPM EJEMPLOS • Escribir un programa que reciba como parámetros el nombre de dos ficheros y copie el contenido del primer fichero en el segundo. int main (int argc, char *argv[]) { char bloque[512]; FILE *f_in, *f_out; Lenguajes de programación LPSI EUI UPM if (3 > argc) { printf (“Nº de parámetros incorrecto.\”); exit (1); } if (! (f_in = fopen (arv[1], “rb”))) { printf (“Error en la apertura del fichero %s.\n”, argv[1]); exit (2); } if (! (f_out = fopen (argv[2], “wb”))) { printf (“Error en la apertura del fichero %s.\n”, argv[2]); fclose (f_in); exit (3); } Lenguajes de programación LPSI EUI UPM while (0 < (leidos = fread(bloque, 1, 512, f_in))) fwrite (bloque, 1, leidos, f_out); fclose (f_in); fclose (f_out); return (0); } Lenguajes de programación LPSI EUI UPM • Escribir un programa que reciba como parámetros los nombres de dos ficheros de alumnos, el primero de ellos el maestro, y el segundo uno de modificaciones, conteniendo registros de alumnos con la información actualizada, que deberán sustituir a los correspondientes registros del maestro. Los ficheros vienen ordenados por dni, y el segundo fichero sólo contiene alumnos que aparecen en el maestro. El programa deberá actualizar el fichero maestro. Lenguajes de programación LPSI EUI UPM • Escribir una función que, recibiendo como parámetro un fichero de texto abierto, conteniendo líneas de un máximo de 255 caracteres, imprima por pantalla la frecuencia de aparición, entre los caracteres del fichero, de cada letra del alfabeto. Se excluye la ‘ñ’. Lenguajes de programación LPSI EUI UPM EJERCICIOS • Escribir un programa que, recibiendo como parámetro el nombre de un fichero de texto, imprima la línea más larga del mismo. • Escribir un programa que, recibiendo como parámetros dos nombres de ficheros, el primero conteniendo matrices de 20x20 enteros, grabe en el segundo la matriz suma de todas las del primer fichero Lenguajes de programación LPSI EUI UPM • Escribir un programa que lea de teclado el nombre de un fichero de texto, que contiene líneas de un máximo de 80 caracteres, y cuente el nº de palabras que hay en él. Se considera que las palabras sólo están formadas por caracteres alfabéticos y no hay palabras partidas entre dos líneas. • Se dispone de un fichero de texto, de nombre “textito.txt”, que contiene un nº indeterminado de líneas, cada una de las cuales conteniendo un nº indeterminado de palabras (separadas por blancos o tabuladores). Escribir un programa que imprima, para cada palabra del fichero, la propia palabra y las vocales que contiene, teniendo en cuenta que si una vocal aparece varias veces, sólo se imprimirá una vez. Lenguajes de programación LPSI EUI UPM • Escribir un programa que, recibiendo como parámetro el nombre de un fichero de texto formado por un nº indeterminado de líneas, compruebe si el fichero está correctamente construido o no. Para ello deberá comprobar que en cada línea sólo hay seis palabras, formadas por un máximo de 10 caracteres alfanuméricos, que entre cada palabra sólo haya un carácter blanco y que no haya caracteres blancos al principio ni al final de la línea. El programa deberá mostrar las líneas mal construidas, precediéndolas por su nº de orden dentro del fichero, o el mensaje “FICHERO CORRECTO”, en caso de que todas las líneas estén bien construidas. Lenguajes de programación LPSI EUI UPM