AnteriorPosterior

6.8 Ejemplo: copiador de ficheros

  Curso: Fundamentos de programación en C, por Nacho Cabanes

6.8 Ejemplo: copiador de ficheros

Vamos a ver un ejemplo, que duplique un fichero de cualquier tipo (no necesariamente de texto), y después veremos las novedades:

/*---------------------------*/
/*  Ejemplo en C nº 58:      */
/*  C058.C                   */
/*                           */
/*  Copiador de ficheros     */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/
 
#include <stdio.h>
 
FILE *fichOrg, *fichDest;        /* Los dos ficheros */
char buffer[2048];               /* El buffer para guardar lo que leo */
char nombreOrg[80],              /* Los nombres de los ficheros */
nombreDest[80];
int cantidad;                    /* El número de bytes leídos */
 
int main()
{
    /* Accedo al fichero de origen */
    printf("Introduzca el nombre del fichero Origen: ");
    scanf("%s",nombreOrg);
    if ((fichOrg = fopen(nombreOrg, "rb")) == NULL)
    {
      printf("No existe el fichero origen!\n");
      exit(1);
 
    }
    /* Y ahora al de destino */
    printf("Introduzca el nombre del fichero Destino: ");
    scanf("%s",nombreDest);
    if ((fichDest = fopen(nombreDest, "wb")) == NULL)
    {
      printf("No se ha podido crear el fichero destino!\n");
      exit(1);
    }
    /* Mientras quede algo que leer */
    while (! feof(fichOrg) )
    {
      /* Leo datos: cada uno de 1 byte, todos los que me caben */
      cantidad = fread( buffer, 1, sizeof(buffer), fichOrg);
      /* Escribo tantos como haya leído */
      fwrite(buffer, 1, cantidad, fichDest);
    }
    /* Cierro los ficheros */
    fclose(fichOrg);
    fclose(fichDest);
 
    return 0;
}
 

Los cambios con relación a lo que conocíamos de ficheros de texto son los siguientes:

* Los ficheros pueden no ser de texto, de modo que leemos uno como fichero binario (con “rb”) y escribimos el otro también como fichero 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 fichero).

* En la misma línea intento abrir el fichero y compruebo si todo ha sido correcto, con

if ((fichOrg = fopen(nombreOrg, "rb")) == NULL)

Esto puede resultar menos legible que hacerlo en dos líneas separadas, como hemos hecho hasta ahora, pero es más compacto, y, sobre todo, muy frecuente encontrarlo en “fuentes ajenos” más avanzados, como los que se puedan encontrar en Internet o cuando se programe en grupo con otras personas, de modo que he considerado adecuado incluirlo.

* 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 el 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 leida sea menos de 2048 bytes, es que el fichero se ha acabado (lo podemos comprobar mirando esta cantidad o con “feof”).

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

Ejercicios propuestos:

  • Crear un ?struct? que almacene los siguientes datos de una persona: nombre, edad, ciudad de residencia. Pedir al usuario esos datos de una persona y guardarlos en un fichero llamado ?gente.dat?, usando ?fwrite?. Cerrar el fichero, volverlo a abrir para lectura y mostrar los datos que se habían guardado, que se deben leer con ?fread?.
  • Ampliar el programa anterior para que use un ?array de structs?, de forma que se puedan tener datos de 10 personas. Se deberá pedir al usuario los datos de las 10 personas y guardarlos en el fichero, usando ?fwrite?. Después se pedirá al usuario un número del 1 al 10 y se mostrarán los datos de la persona indicada por ese número, que se deberán leer de fichero (1 será la primera ficha, y 10 será la última). Por ejemplo, si el usuario indica que quiere ver los datos de la persona 3 (tercera), se deberá leer las dos primeras (con ?fread?), ignorando su contenido, y después leer la tercera, que sí se deberá mostrar.
  • Mejorar la agenda anterior (del apartado 6.4), para guardar y leer cada “ficha” (struct) de una vez, usando fwrite/fread y sizeof, como en el último ejemplo.

Actualizado el: 25-07-2014 16:51

AnteriorPosterior