Píldoras de Vitamina C. freopen
PROGRAMACIÓN
Píldoras de Vitamina C. freopen
2019-05-30
Por
Richi C. Poweri

A decir verdad, nunca he utilizado la función freopen en mi vida. El otro día me la encontré... no recuerdo muy bien dónde, y decidí echarle un vistazo. Esto es lo que aprendí.

Al parecer, el uso principal de esta función es redirigir stdin, stdout y stderr a un determinado fichero. En general la función nos permite hacer esto con cualquier fichero. Bueno, veamos como utilizarla.

Redirigiendo stdout

Vamos a tomar como ejemplo la redirección de stdout a un fichero. En general, cuando necesito hacer esto, simplemente redirección en bash usando algo como miprograma > fichero.txt, pero vamos a ver como podríamos activar y desactivar esta dirección desde nuestro programa.

#include <stdio.h>

int main (void)
{
  FILE *f;
  
  printf ("Mensaje de Error a la consola\n");
  if ((f = freopen ("/tmp/error.log", "wt", stdout)) == NULL)
    {
      fprintf (stderr, "No puedo cambiar stdout\n");
      return -1;
    }
  printf ("Mensaje a fichero??\n");
  fclose (f);
  
  if ((f = freopen (NULL, "", stdout)) == NULL)
    {
      fprintf (stderr, "No puedo cambiar stdout\n");
      return -1;
    }
  
  printf ("De vuelta a la consola\n");
  
  return 0;
}

La primera llamada a freopen es la que se encarga de asociar stdout a un fichero. En este caso /tmp/error.log. Una vez ejecutada la función, todo lo que escribamos en la consola se grabará en el fichero automáticamente.

Una vez que hayamos terminado de escribir datos en el fichero, podemos restaurar la consola. Para ello debemos, primero cerrar el fichero y luego ejecutar freopen de nuevo, pero indicando como nombre de fichero el puntero nulo. El segundo parámetro, el modo, para este caso parece que es ignorado.

Copia mil veces...

A continuación otro ejemplo inspirado en los viejos tiempos de la EGB. El siguiente programa escribe mil veces una frase, pero en lugar de en la pizarra en varios ficheros :). Pero para que resulte un poco más interesante, vamos a utilizar freopen para volcar las frases en diferentes ficheros que no contengan más de 250 líneas... Si, es un ejemplo un poco subrealista.

#include <stdio.h>
#include <string.h>

int main (void)
{
  FILE *f;
  char fname[1024];
  int i = 0, cnt = 0;
  
  snprintf (fname, 1024, "/tmp/file%d.txt", ++i);
  f = fopen (fname, "wt");
  
  while (++cnt < 1000)
    {
      fprintf (f, "%d No usaré el movil en clase\n", cnt);
      if (cnt % 250 == 0)
      {
          snprintf (fname, 1024, "/tmp/file%d.txt", ++i);
          f = freopen (fname, "wt", f);
      }
    }
  fclose (f);
  return 0;
}

El programa es bastante sencillo. Abrimos un fichero y empezamos a escribir. Cada vez que hayamos escrito 250 líneas, simplemente cambiamos el nombre del fichero en el que volcamos los datos, y seguimos escribiendo como si nada.

En este caso freopen es equivalente a una llamada a fclose seguida de una llamada a fopen... Vamos que nos ahorramos una línea de código.

Conclusiones

Pues bien, hasta que me surja un caso de uso más interesante, no creo que utilice esta función muy a menudo. Yo soy más de dup2, pero ha sido interesante aprender como funciona. Si conocéis otros usos interesantes de esta función, no dudéis en dejar vuestros comentarios.


SOBRE Richi C. Poweri
Cuando se trata de programación, Richi es tu chica. Tiene un don especial para los lenguajes de programación, y habla con el sistema operativo de tu a tu. En su tienpo libre Richi ayuda a su familia, en los temas familiares