Está en la página 1de 57

ICAI – 1º Grado en Ingeniería en

Tecnologías Industriales

Fundamentos de Informática

Tema 10
Archivos de Datos -
Ficheros

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 1
Contenidos
• Sección 1: Introducción

• Sección 2: Operaciones básicas con archivos

• Sección 3: Tipos de Archivos

• Sección 4: Archivos de texto

• Sección 5: Archivos binarios


Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 2
Sección 1

• Introducción
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 Archivos
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 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: fscanf () (texto), fread() (binarios)
– Escritura en archivos: fprintf () (texto), fprintf() (binarios)

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 5
Sección 2

• Operaciones básicas con archivos


Operaciones básicas con un archivo
• 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.

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 7
Operaciones básicas con un archivo
• 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 Interna Memoria Externa

Canal físico
Programa Canal lógico
Buffer

Registro buffer: espacio de


memoria interna que reserva el
sistema para el intercambio de
registros entre el archivo y el
Fundamentos de Informática programa. Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 8
Operaciones básicas con un archivo
• 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.

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 9
Operaciones básicas con un archivo
• 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.

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 10
Operaciones básicas con un archivo
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 {
... /*Resto del código*/
}
return 0;
}

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 11
Operaciones básicas con un archivo
• 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 (modo),
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.

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 12
Operaciones básicas con un archivo
• 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”);
} de Informática
Fundamentos Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 13
Operaciones básicas con un archivo
#include <stdio.h>
int main(void)
Declaración de un
{ puntero a archivo
FILE *pfich;
Apertura en modo escritura
pfich = fopen(“datos.txt”,”w”); (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 */
if (fclose(pfich) != 0) {
Cierre del archivo y comprobación de
printf(”\n Error al cerrar el archivo “); si se ha realizado correctamente
}
}
}
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 14
Sección 3

• Tipos de archivos
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).
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 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 (sólo para
archivos de texto).
• Indirectamente: Mediante un programa que reciba información,
la procese y la guarde en un archivo (tanto para archivos de
texto o como binarios).
• La lectura y escritura de archivos varía según el tipo de archivos:
• Texto: fprintf, fscanf, fgets, fputs
• Binarios: fwrite, fread,

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 17
Sección 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 caracteres ASCII:
• 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
• fputs(cadena,puntero)
• fgets(cadena,numero de caracteres,puntero)
• fprintf(puntero,cadena de control,variables)
• fscanf(puntero, cadena de control,variables)

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 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);

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 21
Archivos de texto
• fscanf():
• El funcionamiento es idéntico al de scanf() salvo que ahora es
necesario indicar de 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 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,...);

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 22
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; /*Valor devuelto por fscanf*/
FILE *fichero; /*Puntero al archivo*/
double dato; /*Dato leído del fichero*/
double sum_tot; /*Suma de los datos*/ • El archivo pepe.txt contiene
después de escribir:
/*Abrimos el fichero para introducir datos*/ 1.3
fichero=fopen("c:\\temp\\pepe.txt", "w"); 3.4
if(fichero==NULL){ 4.5
printf("Error de apertura"); 123.4
} • El resultado sería:
else El valor de la suma es:
132.600000
{
fprintf(fichero,"1.3\n3.4\n4.5\n123.4");

1 2
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 23
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, aunque podría haberse evitado abrir y
cerrar si la apertura se hace con “w+” y aquí se usa un rewind(fichero);*/

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
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 24
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");

}
}
}

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 25
Archivos de texto
Cadena de caracteres: fgets(), fputs()
(No las usuremos en este curso para archivos de texto)
• Lectura de una cadena de caracteres:
char * fgets(char *cadena, int tam_cad, FILE *punt_a_arch)
La cadena leída se almacena Al final de la cadena La lectura termina cuando:
en esta variable siempre se añade el ‘\0’ - Encuentra el \n (que sí se copia)
- Encuentra el fin de fich (no se escribe \n)
- Se han leído (tam_cad-1) caracteres
• 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 *punt_a_arch)
Escribe la cadena en el archivo al que apunta
punt_a_arch SIN EL ‘\0’ DEL FINAL
• Valor de retorno:
• Éxito: número positivo si se ha escrito la cadena correctamente
• Error: EOF
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 29
Archivos de texto
(No las usuremos en este curso para 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

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 30
Archivos de texto
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).
• El fichero de texto tiene la información de todos los productos, 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 hasta encontrar el finla del fichero, será
necesario cerrar dicho fichero.
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 36
Archivos de texto
Ejemplo
• Un ejemplo de este fichero de entrada sería:
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);
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 37
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 38
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 39
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 40
Sección 5

• 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
• Es necesario al abrir el fichero poner en el modo ‘b’ de binario.
• Permiten el acceso directo a los datos en el archivo

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 44
Archivos binarios
• 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.
• Valor de retorno: el número de elementos que ha escrito (es decir, numero)
• 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.
• Valor de retorno: el número de elementos que ha leído(es decir, numero)

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 45
Archivos binarios // 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>
Función fread() – Ejemplo 1 #include <stdlib.h>
typedef struct{
char nombre[20];
int existencias;
En el ejemplo tenemos en float precio_unitario;
cuenta que fread() devuelve el }T_ITEM;
número de elementos leídos del int main()
archivo. Si se leen menos {
elementos de los pedidos en la FILE *p_fich;
llamada o bien ha ocurrido un T_ITEM item;
error, o bien se han alcanzado if((p_fich = fopen ("items.dat", "rb"))==NULL) {
el fin del fichero.
printf("ERROR. No se puede abrir el fichero para lectura\n");
En este caso sólo se lee un }
elemento y, por lo tanto, el else {
bucle while continúa leyendo while(fread(&item, sizeof(T_ITEM), 1, p_fich) == 1) {
nuevos registros hasta que el printf("\nNombre del item => %s\n", item.nombre);
valor devuelto por fread() sea printf("Existencias => %d\n", item.existencias);
distinto de 1. printf("Precio unitario => %.2f\n", item.precio_unitario);
}
fclose(p_fich);
}
return 0;
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
} 46
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales
#include <stdio.h>
Archivos binarios #include <stdlib.h>
int main(void)
{
FILE *fp;
int i;
Función fread() – Ejemplo 2 double bal[5] = {1.1, 2.2, 3.3, 4.4, 5.5};

El programa escribe cinco fp=fopen("test.dat", "wb+");


números de tipo double del if (fp==NULL) {
vector bal a un fichero de disco printf("\nNo se puede abrir el fichero\n");
llamado test y, a continuación, }
se leen del disco.
else {
El valor que devuelve fread() fwrite(bal, sizeof(double), 5, fp);
—5 en este caso— se usa para rewind(fp);
comprobar el resultado de la
operación de lectura. En el if(fread(bal, sizeof(double), 5, fp)!=5) {
ejemplo se quiere constatar printf("\nError al leer el fichero\n");
que fread() puede retornar }
valores diferentes a 1. else {
for(i=0; i<5; i++)
printf("%.2f ", bal[i]);
fclose(fp);
}
}
return 0;
Fundamentos de Informática } Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 47
Archivos binarios
Ejemplo: Almacenamiento de estructuras en archivos de binarios
#include <stdio.h> Resultado: no se puede ver pero
#include <stdlib.h> ocupa 28 caracteres (ya que cada
#include <string.h>
#define N 2 estructura ocupa 16 bytes)
/* Declaración de una estructura para los productos
*/
typedef struct {
char nombre[12]; Apertura en
int precio; modo binario
}T_PROD; /*** Creo el archivo ***/
f=fopen("datos.dat","wb");
int main(void)
if (f==NULL) {
{
T_PROD producto[N]; int i; /* contador para los printf("Error al crear el archivo datos.dat\n");
bucles*/ } Tamaño de la
FILE *f; /* Descriptor del archivo de texto */ estructura
else {
/*** Inicializo del vector ***/ for (i=0; i<N; i++) {
strcpy(producto[0].nombre,"CD Rosana"); fwrite (&producto[i] , sizeof(producto[i]) ,1, f);
producto[0].precio=2563;
}
strcpy(producto[1].nombre,"CD Titanic");
producto[1].precio=2628; fclose(f);
} Dirección de la
return 0; estructura a escribir
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales } 48
Archivos binarios
#include <stdio.h>
#include <stdlib.h>
#define N 30
// Para leer lo que se acaba de escribir
typedef struct{
char nombre[N]; rewind(fpunt);
int edad; puts("\nYa hemos leido el fichero y
contiene:\n");
}T_FICHA;
fread(&ficha2, sizeof(T_Ficha), 1 , fpunt);
int main(void)
{ FILE *fpunt; printf("NOMBRE: ");
T_FICHA ficha; puts(ficha2.nombre);
T_FICHA ficha2; printf("EDAD: ");
fpunt=fopen("a:\\datos.dat","wb+"); printf("%d",ficha2.edad);
if (fpunt==NULL) {
printf("\n Error al abrir el fichero "); if (fclose(fpunt) != 0) {
}else{ printf(“Error al cerrar el fichero “);
printf("Introduzca el nombre de la persona:\n"); }
fgets(ficha.nombre, N, stdin); }
printf("Introduzca la edad de la persona:\n"); return 0;
scanf("%d",&ficha.edad); }
fwrite(&ficha, sizeof(T_Ficha), 1, fpunt);

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 49
Ejemplo Opción 1
Archivos binarios
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct{ rewind(punt);
char nombre[30]; puts("\nYa hemos leido el fichero y contiene:\n");
int edad;
}T_Ficha; for (cont=0;cont<N;cont++) {
void main(void)
Lectura de una fread(&lista[cont], sizeof(T_Ficha),1,punt);
{ estructura cada vez printf("NOMBRE: ");
FILE *punt;
T_Ficha ficha; puts(lista[cont].nombre);
T_Ficha lista[N]; printf("EDAD: ");
int cont; printf("%d\n",lista[cont].edad);
punt=fopen(“prueba.txt","wb+"); }
if (punt==NULL) {
printf("\n Error abriendo el fichero "); if (fclose(punt) != 0 ) {
} printf(“Error al cerrar el archivo”);
else { }
for (cont=0;cont<N;cont++) {
fflush(stdin); } /* del 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);
}

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 50
Ejemplo Opción 2
Archivos binarios
#include <stdio.h>
#include <stdlib.h> rewind(punt);
#define N 5 puts("\nYa hemos leido el fichero y contiene:\n");
typedef struct{
char nombre[30]; fread(lista, sizeof(T_Ficha),N ,punt);
int edad; for (cont = 0; cont < N; cont++) {
}T_Ficha; printf("NOMBRE: ");
int main(void) puts(lista[cont].nombre);
{ printf("EDAD: ");
FILE *punt; printf("%d\n",lista[cont].edad);
T_Ficha ficha; Lectura de las N
}
T_Ficha lista[N]; estructuras a la vez
int cont; (sólo es posible If (fclose(punt) != 0 ) {
punt=fopen(“prueba.txt","wb+");
cuando se conoce el printf(“Error al cerrar el archivo”);
if (punt==NULL) {
printf("\n Error abriendo el fichero "); número de registros }
} }
else { que hay) return 0;
for (cont=0;cont<N;cont++) { }
fflush(stdin);
printf("Introduzca el nombre de la
persona:\n");
fgets(ficha.nombre, 30, stdin);
printf("Introduzca la edad de la persona:\n");
scanf("%d",&(ficha.edad));
fwrite(&ficha, sizeof(T_Ficha), 1, punt);

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 51
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

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 52
Archivos binarios

• Ejemplos:
fseek(fp,0,SEEK_SET); /* Va a la primera posición del archivo */
fseek(fp,10*sizeof(T_PRODUCTO),SEEK_SET); /* Va al 11º producto */
fseek(fp,2*sizeof(T_PRODUCTO),SEEK_CUR); /* Se salta dos productos desde la
poisción actual */

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 53
fseek un ejemplo
Archivos binarios
typedef struct {
sencillo

char nombre[40];
char calle [30];
char ciudad[30]; La siguiente función busca la
char provincia[20]; estructura num_cliente
int cod_postal;
}T_INFO;
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);
}
}
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 54
Archivos binarios: ejemplo fseek()
#include <stdio.h> void introducir_datos(T_Lista lista) 1/4
{
#include <stdlib.h>
int cont;
#include <string.h> printf("Introduzca los nombres y edades de 5
personas: \n");
for (cont=0;cont<5;cont++) {
typedef struct{ fflush(stdin);
char nombre[30]; printf("Introduzca el nombre de la persona:\n");
int edad; gets(lista[cont].nombre);
printf("Introduzca la edad de la persona:\n");
}T_Ficha; scanf("%d",&lista[cont].edad);
typedef T_Ficha T_Lista[10]; }
}
void introducir_datos(T_Lista lista);
void pinta_datos(T_Lista lista); void pinta_datos(T_Lista lista)
{
void guardar_fichero(T_Lista lista);
int cont;
void cargar_fichero(T_Lista lista); printf("\n:::::Los datos del fichero leido son:\n");
void modificar(void); for (cont=0;cont<5;cont++) {
printf("NOMBRE: ");
puts(lista[cont].nombre);
int main(void) printf("EDAD: ");
{ printf("%d\n",lista[cont].edad);
}
T_Lista lista,lista2;
}
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 55
Archivos binarios: ejemplo fseek()
void guardar_fichero(T_Lista lista) 2/4
{ void cargar_fichero(T_Lista lista)
FILE *punt; {
int cont; FILE *punt;
int cont=0;
printf("\nGUARDANDO FICHERO....\n"); printf("\nLEYENDO FICHERO.................\n");
punt=fopen("a:datos.dat","wb"); punt=fopen("a:datos.dat","rb");
if (punt==NULL) {
printf("\nERROR"); if (punt==NULL) {
exit(1); printf("\n Error al abrir el fichero");
} exit(1);
}
for(cont=0;cont<5;cont++) { while ( fread(&lista[cont],sizeof(T_Ficha),1,punt)) == 1) {
cont++;
fwrite(&lista[cont],sizeof(T_Ficha),1,punt);
}
}
if (fclose(punt) != 0) {
/* Otra opción en vez del bucle anterior
printf(“Error cerrando el fichero “);
fwrite(lista,sizeof(T_Ficha),5,punt); */
exit(1);
}
if (fclose(punt) != 0) {
printf("\n:::::FICHERO LEIDO:::::\n");
printf(“Error al cerrar el archivo”);
}
exit(1);
}
printf("\n:::::FICHERO GUARDADO:::::\n");
} Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 56
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");
exit(1);
}
do {
fread(&registro,sizeof(T_Ficha),1,punt);
cont++;
} while ((strcmp(registro.nombre,cadena)!=0)&&(cont<5));

CONTINUA EN SIGUIENTE TRANSP.......

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 57
Archivos binarios: ejemplo fseek()
4/4
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");
exit(1);
}
}

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 58
Archivos binario

Ejemplo: Almacenamiento de estructuras en archivos de binarios


#include <stdio.h>
#include <stdlib.h>
#include <string.h> Resultado: no se puede ver pero
ocupa 28 caracteres (ya que cada
#define N 2 // Dimensión de los vec. (núm de productos)
estructura ocupa 14 bytes)

/* Declaración de una estructura para los productos */


typedef struct {
char nombre[12];
Apertura en
int precio; modo binario
}T_PROD;
/*** Creo el archivo ***/
f=fopen("datos.dat","wb");
int main(void) if (f==NULL) {
{ printf("Error al crear el archivo datos.dat\n");
exit(1);
T_PROD producto[N]; /* Vector de productos */ Tamaño de la
} estructura
int i; /* contador para los bucles*/ for (i=0; i<N; i++) {
FILE *f; /* Descriptor del archivo de texto */ fwrite (&producto[i] , sizeof(producto[i]) ,1, f);
}
Dirección de la
fclose(f);
Fundamentos de Informática
/*** Inicializo del vector ***/ estructura
Tema 10: a escribir
Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales } 63
Archivos binarios
#include <stdio.h>
#include <stdlib.h> punt=fopen("a:\\datos.dat","rb");
typedef char T_Cadena30[30];
if (punt==NULL) {
typedef struct{ printf("\n Error al abrir el fichero ");
T_Cadena30 nombre; exit(1);
int edad; }

}T_Ficha; puts("\nYa hemos leido el fichero y contiene:\n");


int main(void) fread(&ficha2, sizeof(T_Ficha), 1 , punt);
{ FILE *punt; printf("NOMBRE: ");
puts(ficha2.nombre);
T_Ficha ficha; printf("EDAD: ");
T_Ficha ficha2; printf("%d",ficha2.edad);
punt=fopen("a:\\datos.dat","wb");
if (fclose(punt) != 0) {
if (punt==NULL) { printf(“Error al cerrar el fichero “);
printf("\n Error al abrir el fichero "); exit(1);
}
exit(1);
}
}
printf("Introduzca el nombre de la persona:\n");
gets(ficha.nombre);
printf("Introduzca la edad de la persona:\n");
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAIscanf("%d",&ficha.edad);
– 1º Grado en Ingeniería en Tecnologías Industriales 64
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 anteman


leyendo registros hasta que se encuentra el fin del fichero

• feof() se puede usar tanto en ficheros binarios como de texto

Fundamentos de Informática Tema 10: Archivos65


de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 65
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;
}
Fundamentos de Informática Tema 10: Archivos66
de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 66
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;
}

Fundamentos de Informática Tema 10: Archivos67


de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 67
1. Programa: Creación de fichero Tienda de licores
• Una tienda de licores necesita un programa C
para hacer control de su almacén. Se quiere
realizar un programa que almacene en un
vector de estructuras la siguiente información:
• Marca del licor
• Número de botellas en el almacén
• Precio unitario
• El programa realizará las operaciones que se
describen a continuación para leer los datos
iniciales de la tienda y guardarlos en el fichero
datos.dat.
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 68
1. Programa: Creación de fichero Tienda de
licores
• Pueden utilizarse las funciones auxiliares que se
estimen convenientes, como mínimo las que se
indican.
1. Entrar en un bucle para preguntar datos de los licores que
hay en el almacén
2. Ir preguntando todos los datos al usuario mediante
llamadas a la función: T_LICORES LeerDato(void);
• Opcional: En lugar de leer los datos de teclado se pueden
leer de un fichero de texto. En este caso utilizar la función
T_LICORES LeerDatos(FILE *fp_txt);
3. Guardar los datos en el archivo datos.dat
4. Preguntar al usuario si ha terminado o no, para salir del
programa o volver a preguntar los datos de otro licor.
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 69
2 Programa: Informe del estado del almacén de
licores

• Para comprobar si el archivos de datos es


correcto, escribir un programa que vaya
leyendo los datos y los vaya mostrando
en pantalla. El programa terminará
cuando se alcance el final del fichero. Se
recuerda que la función fread devuelve
un código que indica si la lectura ha sido
correcta.
• Además, se debe escribir esta misma
información que se lee del fichero
binario, en un fichero de texto.
Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros
ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 71
3. Programa: Gestión de almacén de licores
• Se trata de escribir un programa que permita llevar un control del almacén
conforme se venden botellas.
• El programa entrará en un bucle que realizará las siguientes operaciones:
1. Preguntar la marca del licor y cuántas botellas se venden.
2. Buscar el licor dentro del archivo binario
3. Comprobar que hay botellas suficientes para realizar la venta.
4. Actualizar el fichero descontando el número de botellas vendidas.
5. Si el número de botellas en el almacén es menor o igual a 2, dar un mensaje
para avisar al proveedor.
• Al final del bucle se dará al usuario la opción de terminar el programa. No
hace falta modificar el fichero de datos en el momento de salir porque ya se
ha ido actualizando en cada operación de venta.
• Utilizar el programa 2 para comprobar que las operaciones de venta han sido
correctas. NO se debe usar vector de estructuras en este apartado, el objetivo
es acceder y modificar el fichero mediante fseek().

Fundamentos de Informática Tema 10: Archivos de Datos - Ficheros


ICAI – 1º Grado en Ingeniería en Tecnologías Industriales 73
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.comillas.edu

www.comillas.edu

También podría gustarte