Tema 10 Archivos de datos

Anuncio
Tema 10
Archivos de datos
Fundamentos de Informática
Índice
•
Introducción
•
Operaciones básicas con archivos
•
Tipos de Archivos
•
Archivos de texto
•
Archivos binarios
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
2
1
• Introducción
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
3
Archivos
Un archivo es un conjunto de información que se almacena en un ordenador y puede ser
identificado por su ruta completa, cuyo fin ultimo es guardar o proporcionar información.
Utilizaremos archivos secuenciales.
La memoria RAM se borra en cuanto se corta la corriente.
Es necesario un sistema de almacenamiento secundario.
Los archivos se almacenan en dispositivos de almacenamiento como el disco duro,
diskette, CD ROM, …
El manejo de los sistemas de almacenamiento de los archivos es gestionado por el
sistema operativo.
Carpetas
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Archivos
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
4
Archivos
• Hasta ahora los programas han tomado y devuelto datos de: • teclado ‐ pantalla.
• Una operación de lectura de un fichero es parecida a una operación de lectura de datos desde el teclado
• Una operación de escritura de un fichero es parecida a una operación de escritura en pantalla.
• Utilizaremos archivos secuenciales.
• Operaciones con archivos:
– Apertura de archivos: fopen()
– Cierre de archivos: fclose()
– Lectura de archivos: fprintf()
– Escritura en archivos: fscanf()
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
5
2
Operaciones básicas con archivos
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
6
Operaciones básicas con archivos
• Diferencias con el manejo de pantalla y teclado:
– Es necesario establecer un área de buffer.
• Este área almacena la información mientras se está transfiriendo hacia o desde el fichero.
– Para apuntar a esa área de buffer se utiliza la siguiente declaración:
FILE *punt_fichero;
– Donde:
• FILE es un tipo especial de estructura que establece el área del buffer. Contiene toda la información que necesitan el resto de funciones que trabajan con archivos, como el modo del archivo, los buffers del archivo, errores ...
– Incluida en stdio.h
• punt_fichero es una variable de tipo puntero que apunta al comienzo del área del buffer.
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
7
Operaciones básicas con archivos
• Apertura de un archivo: fopen()
– Siempre antes de realizar cualquier operación con un fichero.
• Una vez abierto el fichero, y hasta que éste se cierre, se pueden realizar tantas operaciones como se deseen sin necesidad de volver a abrirlo.
– El objetivo de abrir un fichero es:
• Asociar el nombre del archivo “físico” con el área del buffer.
• Especificar el uso que se le va a dar al fichero (lectura, escritura, lectura‐escritura, en modo texto, binario ...). Memoria Externa
Memoria Interna
Canal físico
Programa
Buffer
Canal lógico
Departamento de Sistemas Informáticos
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
8
Registro buffer: espacio de memoria interna que reserva el sistema para el intercambio de registros entre el archivo y el programa.
Escuela Técnica Superior de Ingeniería ICAI
Operaciones básicas con archivos
• Apertura de un archivo: fopen()
– Prototipo de la función:
FILE *fopen (char * nombre_completo_archivo, char *modo);
• nombre_completo_archivo (cadena de caracteres): es el nombre del archivo físico sobre el que queremos trabajar.
– Incluyendo el camino completo y la unidad en caso de que fuera necesario.
• modo (cadena de caracteres): indica el uso que vamos a hacer del
fichero o archivo (ver la siguiente transparencia)
• El valor de retorno de fopen():
– Éxito: El puntero al comienzo del área del buffer.
– Fracaso: devuelve NULL si no se pudiera abrir el fichero.
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
9
Operaciones básicas con archivos
•
Apertura de un archivo: Modo
– “r”
» Abre un archivo existente solo para lectura.
– “w”
» Abre un nuevo archivo solo para escritura. En caso de existir un archivo
con ese nombre, lo borra y crea un nuevo archivo vacío.
– “a”
» Abre un archivo para añadir. Si el archivo no existe crea uno nuevo, pero
si existe no borra su contenido. Se posiciona al final del archivo de
forma que sucesivas escrituras se añaden al final del archivo original.
– “r+”
» Abre un archivo existente para actualizarlo (tanto para lectura como para
escritura).
– “w+”
» Abre un archivo nuevo para lectura y escritura. Si existiera un archivo
con ese nombre, lo borra y crea un nuevo archivo vacío.
– “a+”
» Abre un archivo existente para leer y añadir. Si no existiera el archivo se
creará uno nuevo.
– ‘b’
» Hay que añadirle a cualquiera de los modos anteriores cuando se esté
trabajando con datos binarios.
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
10
Operaciones básicas con archivos
Ejemplo
Función fopen(). Apertura para leer y escribir.
#include <stdio.h>
...
int main(void){
FILE *pfich;
...
pfich=fopen(“c:\\temp\\pepe.txt”,“r+”);/*Apertura*/
if(pfich==NULL){ /*Comprobamos apertura*/
printf(“Error: No se puede abrir el archivo.\n”);
}else{
...
}
return 0;
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
11
Operaciones básicas con archivos
• Cierre de un archivo: fclose()
– Su objetivo es liberar el espacio del área del buffer.
– Se escriben a disco todos los datos que aún queden en el buffer, se “desconecta” el archivo del programa y se libera el puntero al archivo.
– Es obligatorio cerrar un fichero cuando se haya terminado con su uso dentro del programa.
– Siempre que queramos cambiar la forma de acceso al fichero, también será necesario cerrarlo y volverlo a abrir especificando el nuevo tipo de acceso para el manejo del fichero.
• Un fichero no puede abrirse mas de una vez sin antes haberlo cerrado.
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
12
Operaciones básicas con archivos
• Cierre de un archivo: fclose()
– Prototipo de la función:
int fclose(FILE *puntero_al_archivo);
• puntero_al_archivo: es el puntero a archivo devuelto por la función fopen() al abrir el archivo que se desea cerrar.
• El valor devuelto por la función es:
0: si el archivo se cerró con éxito, ‐1: si ocurrió algún tipo de error al cerrarlo Independientemente del valor de retorno, el archivo se cierra.
Un error típico es que el disco se ha llenado y no se ha podido vaciar el buffer con la consiguiente pérdida de datos
Ejemplo
Función fclose(). Cierre fichero “pepe.txt” ejemplo anterior.
if(fclose(pfich)!=0){
printf(“Error al cerrar el archivo\n”);
printf(“Posible pérdida de datos”);
}
Departamento de Sistemas Informáticos
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
Escuela Técnica Superior de Ingeniería ICAI
13
Operaciones básicas con archivos
#include <stdio.h>
int main(void)
{
FILE *pfich;
Declaración de un
puntero a archivo
pfich = fopen(“datos.txt”,”w”);
Apertura en modo escritura
(w) del archivo “datos.txt”
Comprobación de que la
if (pfich == NULL) {
apertura ha sido correcta
printf(“\n Error al abrir el fichero”);
}else{
... /* Se utiliza el archivo para escritura */
/* Al acabar de usar el archivo */
Cierre del archivo y comprobación de si
se ha realizado correctamente
if (fclose(pfich) != 0) {
printf(”\n Error al cerrar el archivo “);
}
}
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
14
3
Tipos de archivos
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
15
Tipos de archivos
• Tipos de archivo:
– Texto.
• Archivos ASCII planos, obtenidos y manejados desde programa utilizando cadenas de caracteres.
• Se pueden ver con un editor de texto.
– Binario.
• Archivos con los datos guardados como copia exacta de la memoria del ordenador (binario).
• Sólo comprensible desde un programa que “sepa” qué tipos de datos contiene el archivo y de qué forma están guardados.
• Si se visualizan con un editor de texto no son comprensibles.
• Los archivos binarios y los programa que utilizan archivos binarios no son fácilmente portables a otros ordenadores y otros compiladores (el tamaño de las variables puede variar).
• Los archivos de texto son legibles y fáciles de portar, pero ocupan más espacio para almacenar la información.
• Los archivos binarios no son legibles con un editor de texto y no son portables de un ordenador a otro, pero ocupan menos espacio
• Ejemplo: variable entera de valor 2563 (texto: 4 bytes; binario: 2 bytes).
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
16
Tipos de archivos
•
Creación de un archivo:
– Un archivo secuencial debe ser creado antes de ser procesado.
– Formas de crear un archivo:
Directamente: Mediante el uso de un editor de texto (archivos de texto).
• Indirectamente: Mediante un programa que reciba información, la procese y la guarde en un archivo (texto o binario).
•
•
La lectura y escritura de archivos varía según el tipo de archivos:
– Texto: fprintf, fscanf, getc, putc, fgets, fputs
– Binarios: fwrite, fread, fseek
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
17
4
Archivos de texto
Archivos de Texto
•
•
Son los archivos que contienen caracteres ASCII.
Apertura y cierre de fichero.
–
•
Según lo visto en las transparencias anteriores.
Los archivos guardan cadenas de caracteres:
Es posible utilizar las funciones de biblioteca utilizadas para escribir o leer cadenas vistas a lo largo del curso.
– La diferencia está en que ahora cuando se utilicen estas funciones hay que incluir el puntero al buffer del fichero
• putc(caracter,puntero)
• getc(puntero)
• fputs(cadena,puntero)
• fgets(cadena,numero de caracteres,puntero)
• fprintf(puntero,cadena de control,variables)
• fscanf(puntero, cadena de control,variables)
–
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
19
Archivos de Texto
•
Las funciones fprintf() y fscanf():
–
•
Las propias funciones se encargan de realizar las conversiones de formato que son necesarias para poder transformar los valores binarios usados internamente en el ordenador a cadenas de caracteres usadas en los archivos de texto.
fprintf():
–
–
El funcionamiento es idéntico al de printf() salvo que ahora es necesario indicar en qué archivo ha de escribir.
Valor de retorno: • Éxito: devuelve el número de bytes que ha escrito
• Fracaso: devuelve EOF
fprintf (FILE *puntero_al_archivo, const char *cadena_de_formato,...);
Ejemplo
...
Función fprintf(). Escritura en el fichero “pepe.txt”.
/*Apertura realizada*/
fprintf(pfich,”El valor de %d en hexadecimal es %x\n”,15,15);
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
20
Archivos de Texto
•
fscanf():
–
–
El funcionamiento es idéntico al de scanf() salvo que ahora es necesario indicar en qué archivo ha de leer.
Valor de retorno (cuando sólo se lee un valor): •
•
•
–
Éxito: devuelve el valor 1 si ha leído correctamente
Fracaso: devuelve 0 si ha ocurrido un error en la lectura por una mala especificación de formato.
EOF: si no se ha leído nada porque se ha llegado al final del archivo.
Valor de retorno (cuando sólo se lee más de un valor): •
•
•
El valor devuelto es igual al número de datos leídos si se ha leído correctamente.(devuelve el número de argumentos que han sido leídos y a los que se le ha asignado un valor.)
Si se ha producido algún error antes de leer todos los datos el valor devuelto es igual al número de datos leídos correctamente.
EOF: si no se ha leído nada porque se ha llegado al final del archivo.
int fscanf (FILE *puntero_al_archivo, const char *cadena_de_formato,...);
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
21
Archivos de Texto
/* Programa: Lee el archivo "pepe" que contiene números en punto flotante y calcula su suma.
*/
#include <stdio.h>
int main(void) {
int n;
/* Valor devuelto por fscanf */
FILE *pfich; /* Puntero al archivo */
double dato; /* dato leído del fichero */
double sum_tot; /* Suma de los datos */
pfich = fopen("pepe.txt", "r+");
if (pfich == NULL){
printf("Error: No se puede abrir el fichero \"pepe\"\n");
}else{
•Si el archivo pepe.txt contiene:
1.3
3.4
4.5
123.4
• El resultado sería:
El valor de la suma es:
132.600000
sum_tot = 0; /* Inicialización de la suma antes de entrar en el bucle*/
n = fscanf(pfich, “ %lf ", &dato);
while (n != EOF && n != 0) { /* termina en cuanto ocurra un error de lectura*/
sum_tot+=dato;
n = fscanf(pfich, “ %lf ", &dato);
}
printf("El valor de la suma es: %lf\n", sum_tot);
if( fclose(pfich) != 0){
printf("Error al cerrar el fichero\n");
}
}
return 0;
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
22
8.- Archivos de texto
Ejemplo
Manejo de archivos.
Diseñar un programa que escriba en el fichero “c:\temp\pepe.txt” los números 1.3,
3.4, 4.5 y 123.4 en líneas separadas y cierre el fichero. A continuación es programa
abrirá el fichero para lectura, leerá todos los datos introducidos anteriormente, los
sumará e imprimirá la suma.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{int n;
FILE *fichero;
double dato;
double sum_tot;
/*Valor devuelto por fscanf*/
/*Puntero al archivo*/
/*Dato leído del fichero*/
/*Suma de los datos*/
/*Abrimos el fichero para introducir datos*/
fichero=fopen("c:\\temp\\pepe.txt", "w");
if(fichero==NULL)
printf("Error de apertura");
else
{fprintf(fichero,"1.3\n3.4\n4.5\n123.4");
1
2
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
23
8.- Archivos de texto
1
2
/*Cerramos el fichero*/
if(fclose(fichero)!=0)
{printf("Error al cerrar le fichero\n");
}
}
/*Abrimos el fichero para leer datos*/
fichero=fopen("c:\\temp\\pepe.txt", "r");
if(fichero==NULL)
printf("Error de apertura");
else
{sum_tot=0.0;
n=fscanf(fichero,"%lf",&dato);
while(n!=1)
{sum_tot=sum_tot+dato;
n=fscanf(fichero,"%lf",&dato);
}
1
3
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
24
8.- Archivos de texto
1
3
/*Imprimimos la suma*/
printf(" El valor de la suma es : %lf\n",sum_tot);
/*Cerramos el fichero*/
if(fclose(fichero)!=0)
{printf("Error al cerrar el fichero\n");
}
}
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
25
Archivos de Texto
•
Las funciónes fgets(), fputs(), getc() ó fgetc(), putc() ó fputc()
–
–
•
Son funciones que escriben o leen un carácter (fgetc(), getc(), fputc(), putc()) o cadenas de caracteres (fgets(), fputs())
No realizan conversión de formatos (todo se hace con caracteres)
Lectura de un carácter: int fgetc(FILE *puntero_a_archivo) ó
int getc(FILE *puntero_a_archivo)
–
–
Leen el siguiente carácter del archivo.
Valor de retorno:
•
•
•
Éxito: el carácter leído
Fracaso: Si llega al final de fichero u ocurre un error, el valor de retorno es EOF.
Escritura de un carácter: int fputc(int car, FILE * puntero_a_archivo) ó
int putc(int car, FILE * puntero_a_archivo) –
–
Escriben el carácter car en el archivo al que apunta puntero_a_archivo. Valor de retorno:
•
•
Éxito: el propio carácter escrito
Error: EOF Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
26
Archivos de Texto
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
FILE *punt;
char c;
punt=fopen("datos.txt","w");
if (punt==NULL) {
printf("\n Error – NO SE PUEDE ABRIR EL FICHERO");
}
else {
do {
c = toupper(getchar());
putc(c, punt);
}while (c != '\n');
if (fclose(punt) != 0) {
printf("Error al cerrar el fichero");
}
}
return 0;
}
Departamento de Sistemas Informáticos
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
Escuela Técnica Superior de Ingeniería ICAI
27
Cadena de caracteres: fgets(), fputs()
•
Lectura de una cadena de caracteres:
char * fgets(char *cadena, int tam_cad, FILE *punt_a_arch)
La cadena leída se almacena
en esta variable
–
Valor de retorno:
•
•
•
Al final de la cadena
siempre se añade el ‘\0’
La lectura termina cuando:
- Encuentra el \n (que sí se copia)
- Encuentra el fin de fich (no se escribe \n)
- Se han leído (tam_cad-1) caracteres
Éxito: es un puntero a la cadena leída.
Fracaso: NULL, si se llega al final de fichero u ocurre un error
Escritura de una cadena de caracteres:
int fputs(const char *cadena, FILE *punt_a_arch) –
Valor de retorno:
•
•
Escribe la cadena en el archivo al que apunta
punt_a_arch SIN EL ‘\0’ DEL FINAL
Éxito: número positivo si se ha escrito la cadena correctamente
Error: EOF Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
28
Archivos de Texto
•
Lectura de una cadena de caracteres: char * fgets(char *cadena, int tam_cad, FILE *puntero_a_archivo).
–
–
–
Lee una cadena de caracteres del archivo apuntado por puntero_a_archivo y la almacena en cadena.
La lectura se acaba cuando se encuentra el carácter ‘\n’ (que SÍ se escribe en la cadena), cuando se encuentra el fin de fichero (en este caso no se escribe ‘\n’ en la cadena) o cuando se han leído tam_cad‐1 caracteres. En todos estos casos, se escribe un carácter ‘\0’ en la cadena a continuación del último carácter leído.
Valor de retorno:
•
•
•
Éxito: es un puntero a la cadena leída.
Fracaso: NULL, si se llega al final de fichero u ocurre un error
Escritura de una cadena de caracteres: int fputs(const char *cadena, FILE *puntero_a_archivo) –
–
Escribe la cadena en el archivo al que apunta puntero_a_archivo SIN EL ‘\0’
DEL FINAL.
Valor de retorno:
•
•
Éxito: número positivo si se ha escrito la cadena correctamente
Error: EOF Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
29
Archivos de Texto
Ejemplo 1: OPCION A, lectura de una cadena del teclado, escritura en un
archivo y lectura de esa cadena del archivo
#include <stdio.h>
#include <ctype.h>
int main(void)
{
FILE *punt;
char cadena[80];
char cadena2[80];
punt=fopen("a:\\datos.txt","r");
if (punt==NULL){
printf("\nerror - NO SE PUEDE ABRIR EL FICH ");
}else{
fgets(cadena2,80,punt);
punt=fopen("a:\\datos.txt","w");
if (punt==NULL) {
printf("\n Error - NO SE PUEDE ABRIR
EL FICHERO PARA ESCRIBIR");
}else{
puts("\nIntroduzca una cadena de
caracteres:\n");
gets(cadena);
fputs(cadena,punt);
if (fclose(punt) != 0) {
printf(“Error cerrando el archivo “);
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
if (fclose(punt) != 0) {
printf(“Error al cerrar el archivo”);
}
puts("\nYa hemos leido el fichero y contiene:\n");
puts(cadena2);
}
}
}
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
30
Archivos de Texto
Ejemplo 1: OPCION B, lectura de una cadena del teclado, escritura en un
archivo y lectura de esa cadena del archivo
#include <stdio.h> #include <stdlib.h>
#include <ctype.h>
int main(void)
{
FILE *punt;
char cadena[80];
char cadena2[80];
fgets(cadena2,80,punt);
if (fclose(punt) != 0) {
printf(“Error al cerrar el archivo”);
}
punt=fopen("datos.txt","w+");
if (punt==NULL) {
printf("\n Error - NO SE PUEDE ABRIR
EL FICHERO PARA ESCRIBIR");
}else{
puts("\nYa hemos leido el fichero
contiene:\n");
puts(cadena2);
}
}
puts("\nIntroduzca una cadena de
caracteres:\n");
gets(cadena);
fputs(cadena,punt);
/* Es necesario volver a apuntar al principio del archivo
con el puntero */
rewind(punt);
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
ATENCIÓN
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
31
Archivos de Texto
if (fclose(punt) != 0) {
printf(“Error al cerrar el fichero “);
}
#include <stdio.h>
#include <ctype.h>
#define TAM 80
int main(void)
{
FILE *punt;
char cadena[TAM];
char cadena2[TAM];
char nombre_archivo[TAM];
int n;
}
punt=fopen(nombre_archivo,"r");
if (punt == NULL) {
printf("\n Error - NO SE PUEDE ABRIR EL FICHERO”
“ PARA ESCRIBIR");
}else{
puts("\nYa hemos leido el fichero y contiene:\n");
n = fscanf(punt,"%[^\n]\n",cadena2);
if (n == EOF || n == 0) {
printf(“Error al leer la cadena 2”);
}else{
puts(cadena2);
if (fclose(punt) != 0) {
printf(“Error al cerrar el fichero “);
}
}
}
printf(“Introduzca el nombre del archivo”);
gets(nombre_archivo);
punt=fopen(nombre_archivo,"w");
if (punt == NULL) {
printf("\n Error - NO SE PUEDE ABRIR EL”
“ FICHERO PARA ESCRIBIR");
}else{
puts("\nIntroduzca una cadena de caracteres:\n");
gets(cadena);
fprintf(punt,"%s\n",cadena);
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
}
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
32
Archivos de Texto
Ejemplo: Almacenamiento de estructuras en archivos de texto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 2 /* Dimensión de los vectores (número de
productos) */
/
* Declaración de una estructura para los productos */
typedef struct {
char nombre[12];
int precio;
}PROD;
Resultado: archivo datos.txt
(35 caracteres)
CD Rosana
2563
CD Titanic
2628
/*** Creo el archivo ***/
int main(void)
f = fopen("datos.txt","w");
{
if (f ==NULL) {
PROD producto[N]; /* Vector de productos en el almacén */
printf("Error al crear el archivo datos.txt\n");
int i; /* contador para los bucles*/
}else{
FILE *f; /* Descriptor del archivo de texto */
for (i = 0; i<N; i++) {
fprintf(f,"%s\n",producto[i].nombre);
/*** Inicializo del vector ***/
fprintf(f,"%6d\n",producto[i].precio);
strcpy(producto[0].nombre,"CD Rosana");
}
producto[0].precio=2563;
fclose(f);
strcpy(producto[1].nombre,"CD Titanic");
}
producto[1].precio=2628;
}
Departamento de Sistemas Informáticos
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
33
Escuela Técnica Superior de Ingeniería ICAI
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
34
•
•
•
•
•
•
Ejemplo
Escribir un programa que calcule las pérdidas que tendría un almacén si explotase (es decir, perdiera todos los productos que tiene en el almacén). La información almacenada de cada producto es:
– Nombre del producto
– Número de unidades de ese producto en el almacén
– Precio unitario
Por lo tanto, para poder guardar la información de cada producto, será necesario crearse un tipo de estructura T_PRODUCTO con los campos anteriormente citados.
La información de todos los productos existentes en el almacén está contenida en un fichero de texto llamado “almacen.txt” y que deberá crearse el alumno (se puedo utilizar el ejemplo proporcionado por el profesor en este enunciado) en un editor de texto ASCII (el editor del MinGW es ASCII) para poderlo leer desde su programa.
En el programa principal se debe declarar un vector estático de estructuras T_PRODUCTO para almacenar posteriormente la información de todos los productos del almacén (asignación estática de memoria).
Para saber el número de productos diferentes que hay en el almacén, se ha de abrir el fichero y leer el primer campo, que contiene dicha información.
El fichero de texto tiene la información de todos los productos a continuación del número de productos diferentes, por lo que será necesario ir leyendo el fichero y rellenando el vector de estructuras de tipo T_PRODUCTO. Una vez finalizada la lectura del fichero de texto, será necesario cerrar dicho fichero.
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
35
Ejemplo
Un ejemplo de este fichero de entrada sería:
3
mechas
12
40
detonadores
23
456
dinamita
23
100
mecheros
4
100
• Una vez finalizada la lectura de todos los productos se le debe mostrar al usuario la lista de los productos existentes en el almacén utilizando la función MostrarAlmacen(). • Para calcular cuál sería la pérdida total al destruirse el almacén, se ha de utilizar la función PerdidaTotal() que devuelve la pérdida total, y que tendrá el siguiente prototipo:
double PerdidaTotal(T_PRODUCTO *tabla, int num_productos);
•
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
36
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
37
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
38
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
39
4
Archivos Binarios
Archivos binarios
•
•
•
•
•
•
Los archivos binarios se utilizan para almacenar la información como una copia exacta de la memoria del ordenador.
Normalmente, no se pueden ver con un editor de texto, pues sería una casualidad que los bytes que contienen fuesen caracteres legibles.
Útil cuando se desea guardar en un archivo bloques de información Permite escribir los bloques de una sola vez sin necesidad de escribir cada uno de sus componentes.
Problema de portabilidad
Permiten el acceso directo a los datos en el archivo En estos casos utilizaremos las funciones fwrite() y fread():
–
–
Ambas funciones hacen un acceso directo a la memoria del ordenador a partir de la dirección de estructura.
Escritura:
size_t fwrite(void *estructura, size_t tam, size_t numero, FILE *archivo);
•
–
Toma un número (tam* numero) de bytes de la memoria a partir de la dirección estructura y los escribe en el archivo.
Lectura:
size_t fread (void *estructura, size_t tam, size_t numero, FILE *archivo);
•
Lee del archivo un número (tam* numero) de bytes y los guarda a partir de la dirección de memoria estructura.
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
41
Función fread() – Ejemplo 1
// Programa que lee todos los registros en el fichero items.dat
// y muestra el contenido en la pantalla
// El número de registros no se conoce de antemano
#include <stdio.h>
#include <stdlib.h> typedef struct{
char nombre[20]; int existencias; float precio_unitario; }T_ITEM;
En el ejemplo tenemos en
cuenta que fread() devuelve el
número de elementos leídos del
archivo. Si se leen menos
elementos de los pedidos en la
llamada o bien ha ocurrido un
error, o bien se han alcanzado
el fin del fichero.
En este caso sólo se lee un
elemento y, por lo tanto, el
bucle while continúa leyendo
nuevos registros hasta que el
valor devuelto por fread() sea
distinto de 1.
int main()
{
FILE *p_fich;
T_ITEM item;
if((p_fich = fopen ("items.dat", "rb"))==NULL) {
printf("ERROR. No se puede abrir el fichero para lectura\n");
}
else { while(fread(&item, sizeof(T_ITEM), 1, p_fich) == 1) {
printf("\nNombre del item => %s\n", item.nombre); printf("Existencias => %d\n", item.existencias); printf("Precio unitario => %.2f\n", item.precio_unitario);
}
fclose(p_fich);
}
return 0;
Departamento de Sistemas Informáticos
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
Escuela Técnica Superior de Ingeniería ICAI
}
42
42
Función fread() – Ejemplo 2
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
int i;
double bal[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
fp=fopen("test.dat", "wb+");
if (fp==NULL) {
printf("\nNo se puede abrir el fichero\n");
} else {
fwrite(bal, sizeof(double), 5, fp); rewind(fp);
if(fread(bal, sizeof(double), 5, fp)!=5) {
printf("\nError al leer el fichero\n");
}
else {
for(i=0; i<5; i++)
printf("%.2f ", bal[i]); fclose(fp); }
}
return 0; El programa escribe cinco
números de tipo double del
vector bal a un fichero de disco
llamado test y, a continuación,
se leen del disco.
El valor que devuelve fread()
—5 en este caso— se usa para
comprobar el resultado de la
operación de lectura. En el
ejemplo se quiere constatar
que fread() puede retornar
valores diferentes a 1.
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
43
43
Archivos binario
Ejemplo: Almacenamiento de estructuras en archivos de binarios
#include <stdio.h> #include <stdlib.h> #include <string.h>
#define N 2 // Dimensión de los vec. (núm de productos) /* Declaración de una estructura para los productos */
typedef struct {
char nombre[12];
int precio;
}T_PROD;
int main(void)
{
T_PROD producto[N]; /* Vector de productos */
int i; /* contador para los bucles*/
FILE *f; /* Descriptor del archivo de texto */
Resultado: no se puede ver pero
ocupa 28 caracteres (ya que cada
estructura ocupa 14 bytes)
Apertura en
modo binario
/*** Creo el archivo ***/
f=fopen("datos.dat","wb");
if (f==NULL) {
printf("Error al crear el archivo datos.dat\n");
Tamaño de la
estructura
}else{
/*** Inicializo del vector ***/
strcpy(producto[0].nombre,"CD Rosana");
producto[0].precio=2563;
strcpy(producto[1].nombre,"CD Titanic");
producto[1].precio=2628;
}
for (i=0; i<N; i++) {
fwrite (&producto[i] , sizeof(producto[i]) ,1, f);
}
fclose(f); Dirección de la
estructura a escribir
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
44
Archivos binarios
#include <stdio.h>
#include <stdlib.h>
typedef char T_Cadena30[30];
typedef struct{
T_Cadena30 nombre;
int edad;
}T_Ficha;
int main(void)
{ FILE *punt;
T_Ficha ficha;
T_Ficha ficha2;
punt=fopen("a:\\datos.dat","wb");
if (punt==NULL) {
printf("\n Error al abrir el fichero ");
}else{
printf("Introduzca el nombre de la persona:\n");
gets(ficha.nombre);
printf("Introduzca la edad de la persona:\n");
scanf("%d",&ficha.edad);
fwrite(&ficha, sizeof(T_Ficha), 1, punt);
punt=fopen("a:\\datos.dat","rb");
if (punt==NULL) {
printf("\n Error al abrir el fichero ");
}else{
puts("\nYa hemos leido el fichero y
contiene:\n");
fread(&ficha2, sizeof(T_Ficha), 1 , punt);
printf("NOMBRE: ");
puts(ficha2.nombre);
printf("EDAD: ");
printf("%d",ficha2.edad);
if (fclose(punt) != 0) {
printf(“Error al cerrar el fichero “);
}
}
}
if (fclose(punt) != 0) {
printf(“Error al cerrar el fichero “);
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
45
Ejemplo Opción 1
Archivos binarios
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct{
char nombre[30];
int edad;
}T_Ficha;
int main(void)
{
Lectura de una
FILE *punt;
estructura cada vez
T_Ficha ficha;
T_Ficha lista[N];
int cont;
punt=fopen(“prueba.dat","wb");
if (punt==NULL) {
printf("\n Error abriendo el fichero ");
}else{
for (cont=0;cont<N;cont++) {
fflush(stdin);
printf("Introduzca el nombre:\n");
gets(ficha.nombre);
printf("Introduzca la edad :\n");
scanf("%d",&ficha.edad);
fwrite(&ficha, sizeof(T_Ficha), 1, punt);
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
if (fclose(punt) != 0 ) {
printf(“Error al cerrar el archivo”);
}
}
punt=fopen("prueba.dat ","rb");
if (punt==NULL) {
printf("\n Error abriendo el fichero ");
}else{
puts("\nYa hemos leido el fichero y
contiene:\n");
for (cont=0;cont<N;cont++) {
fread(&lista[cont], sizeof(T_Ficha),1,punt);
printf("NOMBRE: ");
puts(lista[cont].nombre);
printf("EDAD: ");
printf("%d\n",lista[cont].edad);
}
if (fclose(punt) != 0 ) {
printf(“Error al cerrar el archivo”);
}
}
}
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
46
Archivos binarios
Ejemplo Opción 2
#include <stdio.h>
If (fclose(punt) != 0 ) {
printf(“Error al cerrar el archivo”);
#include <stdlib.h>
}
#define N 5
}
punt=fopen("prueba.dat","rb");
de las N
typedef struct{ Lectura
if (punt==NULL) {
estructuras a la vez
printf("\n Error abriendo el fichero ");
char nombre[30];
} else{
int edad;
fread(lista, sizeof(T_Ficha),N ,punt);
}T_Ficha;
puts("\nYa hemos leido el fichero y
contiene:\n");
int main(void)
for (cont = 0; cont < N; cont++) {
printf("NOMBRE: ");
{
puts(lista[cont].nombre);
FILE *punt;
printf("EDAD: ");
printf("%d\n",lista[cont].edad);
T_Ficha ficha;
}
T_Ficha lista[N];
If (fclose(punt) != 0 ) {
int cont;
printf(“Error al cerrar el archivo”);
}
punt=fopen(“prueba.dat","w
}
b");
}
Departamento de Sistemas Informáticos
if (punt==NULL) {Tema 1: Introducción. Arquitectura básica y Sistemas Operativos 47
Escuela Técnica Superior de Ingeniería ICAI
i f("\ E
bi d
Archivos binarios
Permiten el acceso directo a los datos en el archivo utilizando la función fseek().
• Prototipo:
size_t fseek(FILE *archivo, long posicion, int origen);
•
–
–
–
archivo :
• Puntero al buffer del fichero con el que estamos trabajando.
posicion :
• Desplazamiento en bytes a partir de lo que indique origen
origen :
• Especifica donde comienza la búsqueda.
–
–
–
•
SEEK_CUR: Posición actual del puntero.
SEEK_END: Final del fichero.
SEEK_SET: Comienzo del fichero
Valor de retorno:
–
–
Éxito: devuelve 0 (cuando el puntero del archivo se ha movido satisfactoriamente)
Fracaso: devuelve un valor distinto de 0
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
48
48
Archivos binarios
•
Ejemplos: fseek(fp,0,SEEK_SET); /* Va a la primera posición del archivo */
fseek(fp,10*sizeof(producto[0]),SEEK_SET); /* Va al 11º producto */
fseek(fp,2*sizeof(producto[0]),SEEK_CUR); /* Me salto dos productos */
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
49
49
fseek(): Un ejemplo sencillo typedef struct {
char nombre[40];
char calle [30];
char ciudad[30];
char provincia[20];
int cod_postal;
}T_INFO;
La siguiente función busca la
estructura especificada de
tipo T_INFO
void Buscar(int num_cliente)
{
FILE *fp;
T_INFO info;
if((fp=fopen("correo.dat", "rb"))==NULL) {
printf("No se puede abrir el fichero.\n");
}
else {
// Buscar la estructura escogida
fseek(fp, num_cliente*sizeof(T_INFO), SEEK_SET);
// Leer la información a memoria
fread(&info, sizeof(T_INFO), 1, fp);
fclose(fp);
}
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
50
50
Archivos binarios: ejemplo fseek()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char nombre[30];
int edad;
}T_Ficha;
typedef T_Ficha T_Lista[10];
void introducir_datos(T_Lista lista);
void pinta_datos(T_Lista lista);
void guardar_fichero(T_Lista lista);
void cargar_fichero(T_Lista lista);
void modificar(void);
int main(void)
{
T_Lista lista,lista2;
introducir_datos(lista);
guardar_fichero(lista);
modificar();
cargar_fichero(lista2);
pinta_datos(lista2);
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
void introducir_datos(T_Lista lista)
{
int cont;
printf("Introduzca los nombres y edades de 5
personas: \n");
for (cont=0;cont<5;cont++)
{
fflush(stdin);
printf("Introduzca el nombre de la persona:\n");
gets(lista[cont].nombre);
printf("Introduzca la edad de la persona:\n");
scanf("%d",&lista[cont].edad);
}
}
void pinta_datos(T_Lista lista)
{
int cont;
printf("\n:::::Los datos del fichero leido son:\n");
for (cont=0;cont<5;cont++) {
printf("NOMBRE: ");
puts(lista[cont].nombre);
printf("EDAD: ");
printf("%d\n",lista[cont].edad);
}
}
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
51
1/4
Archivos binarios: ejemplo fseek()
void guardar_fichero(T_Lista lista)
{
FILE *punt;
int cont;
printf("\nGUARDANDO FICHERO....\n");
punt=fopen("a:datos.dat","wb");
if (punt==NULL) {
printf("\nERROR");
}else{
void cargar_fichero(T_Lista lista)
{
FILE *punt;
int cont=0;
printf("\nLEYENDO FICHERO.................\n");
punt=fopen("a:datos.dat","rb");
if (punt==NULL) {
printf("\n Error al abrir el fichero");
}else{
while ( fread(&lista[cont],sizeof(T_Ficha),1,punt)) == 1) {
cont++;
}
for(cont=0;cont<5;cont++) {
fwrite(&lista[cont],sizeof(T_Ficha),1,punt);
}
if (fclose(punt) != 0) {
printf(“Error cerrando el fichero “);
}
printf("\n:::::FICHERO LEIDO:::::\n");
/* Otra opción en vez del bucle anterior
fwrite(lista,sizeof(T_Ficha),5,punt); */
if (fclose(punt) != 0) {
printf(“Error al cerrar el archivo”);
}
printf("\n:::::FICHERO GUARDADO:::::\n");
}
}
}
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
2/4
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
52
Archivos binarios: ejemplo fseek()
3/4
void modificar(void)
{
FILE *punt;
T_Ficha registro;
int cont=0;
T_Cadena30 cadena;
fflush(stdin);
printf("\nIntroduzca nombre a buscar:\n");
gets(cadena);
printf("\nLEYENDO FICHERO Y BUSCANDO NOMBRE SOLICITADO..............\n");
punt=fopen("a:datos.dat","rb+");
if (punt==NULL) {
printf("\nERROR");
}else{
do {
fread(&registro,sizeof(T_Ficha),1,punt);
cont++;
} while ((strcmp(registro.nombre,cadena)!=0)&&(cont<5));
CONTINUA EN SIGUIENTE TRANSP.......
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
53
Archivos binarios: ejemplo fseek()
if (strcmp(registro.nombre,cadena)==0)
{
printf("\n..........INDIVIDUO ENCONTRADO..........\n");
printf("\n...DATOS ACTUALES:\n");
printf("NOMBRE: %s\n",registro.nombre);
printf("EDAD: %d\n",registro.edad);
printf("\n:::::INTRODUZCA NUEVOS DATOS:::::::::\n");
fflush(stdin);
printf("Introduzca el nombre de la persona:\n");
gets(registro.nombre);
printf("Introduzca la edad de la persona:\n");
scanf("%d",&registro.edad);
printf("\n..........MODIFICANDO LOS DATOS EN EL FICHERO..........\n");
fseek(punt,(cont-1)*sizeof(T_Ficha),SEEK_SET);
fwrite(&registro,sizeof(T_Ficha),1,punt);
printf("\n..........DATOS MODIFICADOS EN EL FICHERO..........\n");
} else {
printf("\n::::EL NOMBRE SOLICITADO NO SE ENCUENTRA EN EL FICHERO::::\n");
}
if (fclose(punt) != 0) {
printf("\n:::::FICHERO GUARDADO:::::\n");
}
}
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
54
4/4
Función feof()
•
Indica si se ha alcanzado el final del fichero apuntado por fp
•
Prototipo: int feof (FILE *fp);
–
•
fp : es un puntero a un fichero retornado por una llamada a fopen()
Valor devuelto:
–
–
Un valor distinto de 0: cuando se intenta leer un registro del fichero y nos encontramos con un EOF (fin del fichero)
0: en cualquier otro caso
•
Permite leer un fichero cuando el número de registros no se conoce de antemano, leyendo registros hasta que se encuentra el fin del fichero
•
feof() se puede usar tanto en ficheros binarios como de texto
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
55
55
feof(): Ejemplo de fichero binario
// Programa para ilustrar el uso de la función feof() con un fichero binario
#include <stdio.h>
typedef struct{
char nombre[15];
int existencias;
double precio_unitario;
}T_ITEM;
int main(void)
{
FILE *fp;
T_ITEM item;
fp = fopen("items.dat", "rb");
if(fp==NULL) {
printf("\nERROR. No se puede abrir el fichero para lectura\n");
}
else {
fread(&item, sizeof(T_ITEM), 1, fp);
while(!feof(fp)) {
printf("\nNombre=%-15s Existencias=%d Precio=%7.2f",
item.nombre, item.existencias, item.precio_unitario);
fread(&item, sizeof(T_ITEM), 1, fp);
}
fclose(fp);
}
return 0;
}
Departamento de Sistemas Informáticos
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
56
56
Escuela Técnica Superior de Ingeniería ICAI
feof(): Ejemplo de fichero de texto
// Programa para ilustrar el uso de la función feof() con un fichero de texto
#include <stdio.h>
int main(void)
{
FILE *fp;
char nombre[15];
int existencias;
double precio_unitario;
fp = fopen("items.txt", "r");
if(fp==NULL) {
printf("\nERROR. No se puede abrir fichero para lectura\n");
}
else {
fscanf(fp,"%s %d %lf", nombre, &existencias, &precio_unitario);
while(!feof(fp)) {
printf("\nArticulo=%-15s Existencias=%3d Precio=%8.2f",
nombre, existencias, precio_unitario);
fscanf(fp,"%s %d %lf", nombre, &existencias, &precio_unitario);
}
fclose(fp);
}
return 0;
}
Departamento de Sistemas Informáticos
Escuela Técnica Superior de Ingeniería ICAI
Tema 1: Introducción. Arquitectura básica y Sistemas Operativos
57
57
Escuela Técnica Superior de Ingeniería ICAI
Alberto Aguilera 25
28015 Madrid
Tel +34 91 542 28 00
Fax + 34 91 542 31 76
Iwww.icai.upcomillas.es
www.upcomillas.es
Descargar