Existen numerosas funciones para realizar operaciones de entrada/salida sobre ficheros. Las más usadas son:
fprintf(FILE *nombre, const char *format ). Donde FILE *nombre es la variable puntero a FILE que usemos para identificar el fichero y const char *format tiene el mismo significado y formato que en printf(). Esta función se utiliza para escribir datos en ASCII en un fichero. En caso de éxito, esta funciones devuelven el numero de caracteres impresos (no incluyendo el caracter `\0' usado para terminar la salida de cadenas). Si se encuentra un error de salida, se devuelve un valor negativo. Tanto en ésta, como en el resto de funciones que veremos, el valor devuelto sirve para comprobar que la operación se ha realizado con éxito.
fscanf(FILE *nombre, const char *format). Los argumentos tienen el mismo significado que en fprintf(). Se usa para leer datos de un fichero en ASCII. El valor devuelto es el número de datos, no de caracteres, leídos.
fwrite(const void *ptr, size_t tam, size_t nmiemb, FILE *nombre). Función para escritura de datos en binario en un fichero. Escribe nmiemb elementos de datos, cada uno de tam bytes de largo, al fichero apuntado por nombre, obteniéndolos del sitio apuntado por ptr, esto es, ptr es un puntero a una variable, vector, estructura, etc, tal que su tamaño sea de tam*nmiemb bytes. tam y nmiemb son datos enteros. Devuelve el número de elementos (no de bytes) escritos correctamente. Si ocurre un error o se llega al fin-de-fichero, el valor devuelto es un número menor del esperado (o cero).
fread(void *ptr, size_t tam, size_t nmiemb, FILE *nombre). Función para lectura de datos en binario en un fichero. El significado de los parámetros de la función es el mismo que para fwrite salvo ptr que es un puntero a la zona de memoria donde se almacenará la información leida. El valor devuelto es el mismo que en fwrite pero en este caso haciendo referencia al número de datos leídos.
Otras funciones para entrada/salida son: fgets, fgetchar, fputs, fputchar. Su funcionamiento es similar a las de nombre parecido (sin la f inicial) que sirven para entrada/salida desde la estándar correspondiente. La búsqueda de más información se deja para el estudiante.
fseek( FILE *nombre, long desplto, int origen). Sirve para el control de flujo de datos sobre un fichero, más concretamente mueve el indicador que marca la posición de escritura/lectura en el fichero correspondiente. La nueva posición del indicador, medida en bytes, se obtiene añadiendo desplto bytes a la posición especificada por origen. Para especificar el punto de origen del desplazamiento se pueden usar la siguientes constantes:
SEEK_SET. Comienzo del fichero.
SEEK_CUR. Posición actual.
SEEK_END. Fin de fichero.
En caso de que todo haya ido correcto en la operación esta función devuelve un 0, y si ha habido error un -1.
rewind( FILE *nombre). Es la versión rápida de fseek(nombre, 0, SEEK_SET), es decir, mover el apuntador al comienzo del fichero. Esta función no devuelve nada.
feof(FILE *nombre). Devuelve un valor distinto de 0 si el indicador de fichero ha llegado al final, y 0 en caso contrario.
Ejemplo_Fich_1. De manejo de ficheros. Este programa debe recibir 2 argumentos. El primero es un fichero de texto con cantidades reales. Lee esas cantidades y las almacena en formato float (binario) en el fichero incluido como segundo argumento. Cada valor leído es mostrado por pantalla usando fprintf para mostrar el uso del puntero a la salida estándar "stdout".
#include<stdio.h>
main (int argc, char **argv)
{
FILE *fpin, *fpout_fich, *fpout_std;
float dat;
int cont=0;
if (argc < 3)
{
fprintf (stderr,"ERROR numero de argumentos insuficiente\n");
exit (1);
}
if ( (fpin = fopen(argv[1], "r")) == NULL)
{
fprintf (stderr,"ERROR No se pudo abrir %s\n", argv[1]);
exit (2);
}
if ( (fpout_fich = fopen(argv[2], "wb")) == NULL)
{
fprintf (stderr,"ERROR No se pudo abrir %s\n", argv[2]);
exit (2);
}
fpout_std = stdout;
fscanf (fpin,"%f",&dat);
while (!feof(fpin))
{
if ( fwrite(&dat, sizeof(float), 1, fpout_fich) != 1)
{
fprintf(stderr, "ERROR al escribir dato %d en %s\n", cont, arg[2]);
exit(3);
}
fprintf (fpout_std,"Dato escrito %.2f\n",dat); // se muestra con 2 decimales
fscanf (fpin,"%f",&dat);
cont++;
}
fclose (fpin);
fclose (fpout_fich);
return 0;
}
Ejercicio _Fich_1. Modificar la condición de finalización de lectura de fichero en el ejemplo anterior, usando el valor devuelto por fscanf().
Ejercicio_Fich_2. Modificar el ejemplo anterior de la siguiente manera: tras cerrar los dos ficheros, abrir el introducido como segundo argumento (el que hemos creado en binario) y leer los datos en él almacenados mostrándolos por pantalla, para ver que su contenido es correcto (el mismo que tenía el fichero de texto introducido como primer argumento).