No es un bug, es una característica no documentada

sábado, 29 de noviembre de 2014

Programación. Ficheros en C

22:34 Posted by Inazio , 1 comment
Operaciones sobre ficheros


Abrir, leer, escribir y cerrar ficheros

Abrir fichero


Consiste en asociar un nombre de fichero a una variable e indicar la operación que se va a realizar sobre él (leer, escribir o añadir).

Necesitamos pues una variable que nos permita manejar el fichero.

FILE*fichero

Esto es un puntero a una estructura con información sobre el fichero. Nos da igual como sea esa estructura. Nosotros se la pasamos a las funciones que hay para trabajar con ficheros y ellos harán con ella lo que tengan que hacer

Para abrir un fichero usamos la función fopen, tanto para ficheros de texto como para binarios.

Función fopen()

FILE*fopen(const char *nombreFichero, const char *modo)

è nombreFichero: Cadena con el nombre del fichero
è modo: Cadena que indica el modo
·         r – Lectura. El fichero ha de existir. Si no, da error
·         w – Escritura. Si el fichero no existe se crea uno nuevo con ese nombre
Si existe, se borra todo su contenido y se empieza a escribir al principio
·         a – Añadir al final del fichero. Se abre para escritura añadiendo datos al final del fichero. Si no existe se crea uno nuevo

Devuelve puntero de FILE y NULL si la apertura falla

Cuando se abre un fichero para lectura no se puede utilizar para escritura y viceversa. Se cierra y vuelve a abrirse para hacer la otra operación.

Uso de fopen()

FILE*fich
fich=fopen(“ejemplo.txt”,”r”);
if (fich==NULL)
       printf(“Error en la apertura del fichero \n”);
else {
       …
}

Lectura y escritura de un fichero en modo texto


Igual que la lectura/escritura por teclado/pantalla pero haciéndolo sobre un fichero.
Se usan las funciones fprintf y fscanf en vez de printf y scanf.
Tienen un parámetro más (el primero) que indica en que fichero escribir o leer. Por lo demás, funcionan exactamente igual que los otros dos.

fprintf(fich,”%i”,&numero);
fscanf(fich,”%i”,&numero);

Lectura y escritura de un fichero en modo binario


Los datos se vuelcan tal y como están en memoria.
Adecuado para datos complejos (structs y matrices)
Un fichero binario no es editable (o lo es, pero sólo veremos símbolos raros)

De nuevo dos funciones

fread(ptDato,N,k,fichero);
fwrite(ptDato,N,k,fichero);

En ambos:
è ptDato. Puntero a donde se encuentran los datos
è N. Tamaño del elemento
è k. Número de elementos
è Fichero. Puntero de tipo FILE

Ambas funciones devuelven el número de elementos leídos/escritos correctamente. Si el número es menor del esperado algo ha pasado:
1.      Error
2.      Se ha llegado al final del fichero (en el caso de lectura)

fread y fwrite

Aquí es donde resulta realmente útil la función sizeof() que ya hemos empleado alguna vez. Ejemplo:

FILE*fich
struct medida {
       int hora;
       int minuto;
       float valor;
}*dato
fread(dato,sizeof(struct medida),1,fich);
fwrite(dato,sizeof(struct medida),1,fich);

Cierre de un fichero


Operación muy importante que supone el fin del tratamiento del fichero. En caso de escritura, asegura que se han escrito todos los datos en el disco

fclose(fich)

feof()


Control de lectura. Para saber cuándo se llega al final del fichero existe la función feof()

Devuelve:
è CIERTO cuándo ya hemos leído todos los datos del fichero
è FALSO cuándo aún quedan datos por leer

leer(fichero,dato);
mientras que (!feof(fich)) {
       procesarDato();
       leer(fich,dato);
}
fmq

Es decir, el fin de fichero es como si fuera un caracter que se lee, y es entonces cuando comprobamos a ver si ya hemos llegado al final.

Ejercicios de práctica


1.      Tenemos un fichero de texto que contiene muchos enteros (eso sí, esa cantidad es múltiplo de diez). Se trata de ir leyendo datos de ese fichero de texto e ir calculando y mostrando por pantalla las medidas de los números de 10 en 10. Es decir, primero la media de los 10 primeros, luego la media de los 10 segundos, y así hasta que el fichero termine

Solución

#include <stdio.h>

main() {
   FILE*f;
   int dato, suma, i;
   f=fopen(“fichero.txt”,”r”);
   if (f==NULL)
     printf(“Error en la apertura”);
   else {
     fscanf(f,”%i”,&dato);
     while (!feof(f)) {
          suma=0;
         for(i=0;i<10;i++) {
              suma+=dato;
              fscanf(f,“%i”,&dato);
         }
         printf(“La media es %d \n”,suma/10);
     }
     fclose(f);
   }
}

2.   Tenemos un fichero de registros “fichero.dat” cuyas componentes están definidas según la declaración siguiente:

typeof struct registro1 {
            char partido[60];
            char localidad[60];
            int candidatos;
}ANTES;

Se quiere sustituir la estructura del registro por la siguiente:

typeof struct registro1 {
            char partido[60];
            char localidad[60];
            int candidatos, elegidos;
} DESPUES;

Escribe un programa que modifique la estructura y traspase toda la información del fichero primitivo a “nuevo.dat”, inicializando a 0 el nuevo campo creado.

Solución

ANTES antes;
DESPUES después;
FILE*old*new;
old=fopen(“fichero.dat”,”r”);
new=fopen(“nuevo.dat”,”w”);
fread(&antes,sizeof(antes),1,old);
while (!feof(old)) {
   strcpy(despues.partido, antes.partido);
   strcpy(despues.localidad, antes.localidad);
   despues.candidatos=antes.candidatos;
   despues.elegidos=0;
   fwrite(&despues,sizeof(despues),1,new);
   fread(&antes,sizeof(antes),1,old);
}
fclose(old);
fclose(new);

1 comentario: