Programación
(L109)
Sesión: 11
Ing. José C. Benítez P.
Archivos
Programación - Prof. Ing. Jose C. Benitez P. 2
Sesión 11. Temas
Archivos
� Introducción
� Escritura en un archivo de texto
� Lectura de un archivo de texto
� Lectura hasta el final de un archivo
� Leer y escribir en un archivo letra a letra
� Modos de apertura de un archivo
� Archivos binarios
� Copiador de archivos
Programación - Prof. Ing. Jose C. Benitez P. 3
Archivos. Introducción
� Con archivos, siempre se realiza cinco operaciones básicas:
� Declarar la variable archivo.
� Abrir el archivo.
� Leer datos del archivo.
� Escribir datos en archivo.
� Cerrar el archivo.
� No siempre podremos realizar esas operaciones, así que
además tendremos que comprobar los posibles errores.
� Por ejemplo, puede ocurrir que intentemos abrir un archivo
que realmente no exista, o que queramos escribir en un
dispositivo que sea sólo de lectura.
Programación - Prof. Ing. Jose C. Benitez P. 4
Archivos: Escritura en un archivo de texto
� Ejemplo: Se crea un archivo de texto y se escribe algo en él:
#include <stdio.h>main(){
FILE* archivo; // Se declara la variable archivoarchivo = fopen("prueba.txt", "wt"); // Se abre archivofputs("Esto es una línea\n", archivo); // Se escribefputs("Esto es otra", archivo);fputs(" y esto es continuación de la anterior\n", archivo);fclose(archivo);// Se cierra archivo
}
Programación - Prof. Ing. Jose C. Benitez P. 5
Archivos: Escritura en un archivo de texto
� FILE * es el tipo de datos puntero asociado a un archivo.
� Para abrir el archivo usamos fopen, que necesita dos datos:
el nombre del archivo y el modo de lectura. El modo de
lectura estará formado por varias letras, de las cuales por
ahora nos interesan dos: w indica que queremos escribir
(write) en el archivo, y t avisa de que se trata de un archivo
de texto (text). Como abrimos el archivo para escribir en él,
se creará el archivo si no existía, y se borrará su contenido si
ya existía (más adelante veremos cómo añadir a un archivo
sin borrar su contenido).
Programación - Prof. Ing. Jose C. Benitez P. 6
Archivos: Escritura en un archivo de texto
� Para escribir en el archivo y para leer de él, tendremos
órdenes muy parecidas a las que usábamos en pantalla. Por
ejemplo, para escribir una cadena de texto usaremos fputs,
que recuerda mucho a puts pero con la diferencia de que no
avanza de línea después de cada texto (por eso hemos
añadido \n al final de cada frase).
� Finalmente, cerramos el archivo con fclose.
Programación - Prof. Ing. Jose C. Benitez P. 7
Archivos: Lectura de un archivo de texto
� Si queremos leer de un
archivo, los pasos son
muy parecidos, sólo que
lo abriremos para lectura
(el modo de lectura
tendrá una r de read, en
lugar de w), y leeremos
con fgets:
#include <stdio.h>
main(){
FILE* archivo;char nombre[80] = "c:\\autoexec.bat";char linea[81];archivo = fopen(nombre, "rt");if (archivo == NULL){printf("No existe el archivo!\n");exit(1);}
fgets(linea, 80, archivo);puts(linea);fclose(archivo);
}
Programación - Prof. Ing. Jose C. Benitez P. 8
Archivos: Lectura de un archivo de texto
� En el nombre del archivo, hemos indicado un
nombre algo más complejo. En estos casos, hay
que recordar que si aparece alguna barra
invertida (\), deberemos duplicarla, porque la
barra invertida se usa para indicar ciertos códigos
de control. Por ejemplo, \n es el código de avance
de línea y \a es un pitido. El modo de lectura en
este caso es r para indicar que queremos leer
(read) del archivo , y t avisa de que es un archivo
de texto.
Programación - Prof. Ing. Jose C. Benitez P. 9
Archivos: Lectura de un archivo de texto
� Para leer del archivo y usaremos fgets, que se parece
mucho a gets, pero podemos limitar la longitud del
texto que leemos (en este ejemplo, a 80 caracteres)
desde el archivo . Esta cadena de texto conservará
los caracteres de avance de línea.
� Si no se consigue abrir el archivo , se nos devolverá
un valor especial llamado NULL (puntero).
� La orden exit es la que nos permite abandonar el
programa en un punto. La veremos con más detalle
un poco más adelante.
Programación - Prof. Ing. Jose C. Benitez P. 10
Archivos: Lectura hasta el final del archivo
� Normalmente no querremos
leer sólo una frase del archivo,
sino procesar todo su
contenido.
� Para ayudarnos, tenemos una
orden que nos permite saber si
ya hemos llegado al final del
archivo. Es “feof” (EOF es la
abreviatura de End Of File, fin
de archivo).
� Por tanto, nuestro programa
deberá repetirse mientras que
no se acabe el archivo,
main(){FILE* archivo;char nombre[80] = "c:\\autoexec.bat";char linea[81];archivo = fopen(nombre, "rt");if (archivo == NULL){printf("No existe el archivo!\n");exit(1);}while (! feof(archivo)) {fgets(linea, 80, archivo);puts(linea);}fclose(archivo);}
Programación - Prof. Ing. Jose C. Benitez P. 11
Archivos: Lectura hasta el final del archivo
� Esa será la estructura básica de casi cualquier
programa que debe leer un fichero completo, de
principio a fin:
� Declarar el puntero a archivo: FILE *archivo
� Abrir con: archivo = fopen(nombre, "rt")
� Comprobar que se ha podido acceder
correctamente con: if (archivo == NULL) { … }
� Leer con while !(feof(…))” y
� Cerrar con fclose(archivo)
Programación - Prof. Ing. Jose C. Benitez P. 12
Archivos: Archivos con tipo
� Es frecuente que los archivos que queramos manejar no
sean de texto, pero que aun así tengan un formato
bastante definido.
� Por ejemplo, podemos querer crear una agenda, en la
que los datos de cada persona estén guardados en un
struct. En este caso, podríamos guardar los datos usando
fprintf y fscanf, análogos a printf y scanf que ya
conocemos.
fprintf( archivo, "%40s%5d\n", persona.nombre, persona.numero);
fscanf(archivo, "%40s%5d\n", &persona.nombre, &persona.numero);
Programación - Prof. Ing. Jose C. Benitez P. 13
Archivos: Archivos con tipo
� Como se ve en el ejemplo, es recomendable indicar la
anchura que debe tener cada dato cuando guardamos
con fprintf, para que se pueda recuperar después de la
misma forma con fscanf.
� Aun así, fscanf tiene el mismo problema que scanf: si
leemos una cadena de texto, la considera terminada
después del primer espacio en blanco, y lo que haya a
continuación lo asignará a la siguiente cadena. Por eso,
cuando manejemos textos con espacios, será
preferible usar fgets o bien otras dos órdenes para
manejo de archivos que veremos más adelante.
Programación - Prof. Ing. Jose C. Benitez P. 14
Archivos: Leer y escribir archivos letra a letra
� Si queremos leer o escribir sólo una letra en un
archivo, tenemos las órdenes fgetc y fputc, que se
usan:
letra = fgetc(archivo );
fputc (letra, archivo );
Programación - Prof. Ing. Jose C. Benitez P. 15
Archivos: Modos de apertura de archivos
� Las letras que pueden aparecer en el modo de
apertura del archivo, para poder añadir datos a un
archivo ya existente son:
Tipo Significado
r Abrir sólo para lectura.
w Crear para escribir. Sobreescribe el archivo si ya existe
(borrando el original).
a Añade al final del fichero si existe, o lo crea si no existe.
+ Se escribe a continuación de los modos anteriores para
indicar que también queremos modificar. Por ejemplo: r+
permite leer y modificar el archivo
t Abrir en modo de texto.
b Abrir en modo binario.
Programación - Prof. Ing. Jose C. Benitez P. 16
Archivos binarios
� Hasta ahora hemos visto los archivos de texto, que son
sencillos de crear y de leer.
� Pero también podemos manejar archivos que
contengan información de cualquier tipo.
� En este caso, utilizamos “fread” para leer un bloque de
datos y “fwrite” para guardar un bloque de datos.
Estos datos que leamos se guardan en un buffer (una
zona intermedia de memoria).
� En el momento en que se lean menos bytes de los que
hemos pedido, quiere decir que hemos llegado al final
del archivo.
Programación - Prof. Ing. Jose C. Benitez P. 17
Archivos binarios
� En general, el manejo de “fread” es el siguiente:
� cantidadLeida = fread(donde, tamañoDeCadaDato,
cuantosDatos, fichero);
� Por ejemplo, para leer 10 números enteros de un
archivo (cada uno de los cuales ocuparía 4 bytes, si
estamos en un sistema operativo de 32 bits), haríamos
int datos[10]; resultado = fread(&datos, 4, 10, archivo); if (resultado < 10) printf("Había menos de 10 datos!");
Programación - Prof. Ing. Jose C. Benitez P. 18
Archivos binarios
� Al igual que ocurría con “scanf”, la variable en la que
guardemos los datos se deberá indicar precedida del símbolo
&. También al igual que pasaba con “scanf”, si se trata de una
cadena de caracteres, como char dato[500] no será necesario
indicar ese símbolo &. Ejemplo:
char cabecera [40]; resultado = fread(cabecera, 1, 40, archivo); if (resultado < 40)
printf("Formato de fichero incorrecto, no está toda la cabecera!"); else
printf("El byte en la posición 5 es un %d”, cabecera[4]);
Programación - Prof. Ing. Jose C. Benitez P. 19
Copiador de Archivos
Vamos a ver un ejemplo, que duplique un archivo de cualquier tipo (no
necesariamente de texto), y después veremos las novedades:
#include <stdio.h>
FILE *archOrg, *archDest; /* Los dos archivos*/ char buffer[2048]; /* El buffer para guardar lo que leo */ char nombreOrg[80], /* Los nombres de los archivos*/ nombreDest[80]; int cantidad; /* El número de bytes leídos */
main() {
/* Archivo de origen */ printf("Introduzca el nombre del archivo Origen: "); scanf("%s",nombreOrg); if ((archOrg = fopen(nombreOrg, "rb")) == NULL) { printf("No existe el archivo origen!\n"); exit(1);
} /* Archivo de destino */ printf("Introduzca el nombre del archivo Destino: "); scanf("%s",nombreDest);
if ((archDest = fopen(nombreDest, "wb")) == NULL) { printf("No se ha podido crear el archivo destino!\n"); exit(1);
} /* Mientras quede algo que leer */ while (! feof(archOrg) ) { /* Leo datos: cada uno de 1 byte, todos los que me caben */ cantidad = fread( buffer, 1, sizeof(buffer), archOrg); /* Escribo tantos como haya leído */ fwrite(buffer, 1, cantidad, archDest);
} /* Cierro los archivos*/ fclose(archOrg); fclose(archDest);
}
Programación - Prof. Ing. Jose C. Benitez P. 20
Copiador de Archivos
Los cambios con relación a lo que conocíamos de archivos de
texto son los siguientes:
� Los archivos pueden no ser de texto, de modo que leemos
uno como archivo binario (con “rb”) y escribimos el otro
también como archivo binario (con “wb”).
� Definimos un buffer de 2048 bytes (2 K), para ir leyendo la
información por bloques (y guardando después cada bloque
en el otro archivo).
� En la misma línea intento abrir el archivo y compruebo si
todo ha sido correcto, con:
if ((fichOrg = fopen(nombreOrg, "rb")) == NULL)
Programación - Prof. Ing. Jose C. Benitez P. 21
Copiador de Archivos
� A “fread” le digo que queremos leer 2048 datos de 1
byte cada uno, y él nos devuelve la cantidad de bytes
que ha leído realmente. Para que la fuente sea más
fácil de aplicar a otros casos en los que no sean
bloques de 2048 bytes exactamente, suele ser
preferible indicar que queremos leer el tamaño del
bloque, usando “sizeof”:
cantidad = fread( buffer, 1, sizeof(buffer), fichOrg);
� Cuando la cantidad leída sea menos de 2048 bytes, es
que el archivo se ha acabado (lo podemos comprobar
mirando esta cantidad o con “feof”).
Programación - Prof. Ing. Jose C. Benitez P. 22
Copiador de Archivos
� “fwrite” se maneja igual que fread: se le indica
dónde están los datos, el tamaño de cada dato,
cuantos datos hay que escribir y en qué fichero
almacenarlos. En nuestro ejemplo, el número de
bytes que debe escribir será el que haya leido:
fwrite(buffer, 1, cantidad, fichDest);
Programación - Prof. Ing. Jose C. Benitez P. 23
Tarea (T11)
Hacer un programa en C utilizando archivos:
1. Un programa que pida al usuario que teclee frases, y las almacene en el
fichero “frases.txt”. Acabará cuando el usuario pulse Intro sin teclear nada.
2. Un programa que pregunte un nombre de fichero y muestre en pantalla el
contenido de ese fichero, haciendo una pausa después de cada 25 líneas,
para que dé tiempo a leerlo. Cuando el usuario pulse intro, se mostrarán
las siguientes 25 líneas, y así hasta que termine el fichero.
3. Una agenda que maneje los siguientes datos: nombre, dirección, tlf móvil,
email, y día, mes y año de nacimiento (estos tres últimos datos deberán
ser números enteros cortos). Deberá tener capacidad para 100 fichas. Se
deberá poder añadir un dato nuevo, visualizar los nombres de las fichas
existentes, o mostrar todos los datos de una persona (se preguntará al
usuario cual es el nombre de esa persona que quiere visualizar). Al
empezar el programa, leerá los datos de un fichero llamado “agenda.dat”
(si existe). Al terminar, guardará todos los datos en ese fichero.
4. Mejorar la agenda anterior, para guardar y leer cada “ficha” (struct) de una
vez, usando fwrite/fread y sizeof, como en el último ejemplo.
Presentación
24Programación - Prof. Ing. Jose C. Benitez P.
�Todos los códigos fuentes deben ser presentados en un
solo archivo de texto, cuyo nombre lleve las iniciales del
curso, sus Apellidos, guion bajo y luego el numero de la
tarea. Ejemplo:
PRG_BenitezPalacios_T11.txt
� Los códigos deben estar comentados bloque a bloque.
� La presentación de esta Tarea es obligatoria y tiene 03
puntos de bonificación en la Tercera Practica Calificada.
Plazo de entrega: Lunes 20/02/12
Las Tareas que no cumplan las indicaciones no serán
recepcionados por el profesor.
Programación - Prof. Ing. Jose C. Benitez P. 25
Sesión 11. Archivos
Programación
http://utpprogc.blogspot.com
Top Related