utp pti_s11_archivos

25
Programación (L109) Sesión: 11 Ing. José C. Benítez P. Archivos

Upload: c09271

Post on 10-Feb-2017

811 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Utp pti_s11_archivos

Programación

(L109)

Sesión: 11

Ing. José C. Benítez P.

Archivos

Page 2: Utp pti_s11_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

Page 3: Utp pti_s11_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.

Page 4: Utp pti_s11_archivos

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

}

Page 5: Utp pti_s11_archivos

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).

Page 6: Utp pti_s11_archivos

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.

Page 7: Utp pti_s11_archivos

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);

}

Page 8: Utp pti_s11_archivos

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.

Page 9: Utp pti_s11_archivos

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.

Page 10: Utp pti_s11_archivos

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);}

Page 11: Utp pti_s11_archivos

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)

Page 12: Utp pti_s11_archivos

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);

Page 13: Utp pti_s11_archivos

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.

Page 14: Utp pti_s11_archivos

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 );

Page 15: Utp pti_s11_archivos

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.

Page 16: Utp pti_s11_archivos

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.

Page 17: Utp pti_s11_archivos

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!");

Page 18: Utp pti_s11_archivos

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]);

Page 19: Utp pti_s11_archivos

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);

}

Page 20: Utp pti_s11_archivos

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)

Page 21: Utp pti_s11_archivos

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”).

Page 22: Utp pti_s11_archivos

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);

Page 23: Utp pti_s11_archivos

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.

Page 24: Utp pti_s11_archivos

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.

Page 25: Utp pti_s11_archivos

Programación - Prof. Ing. Jose C. Benitez P. 25

Sesión 11. Archivos

Programación

http://utpprogc.blogspot.com