4.4 Escritura de archivos

Una de las opciones más interesantes de la programación es la posibilidad de guardar el resultado de los programas en archivos, que podrán ser utilizados más adelante o compartidos con otros usuarios. Hay varias formas de manejar archivos, vamos a ver la más sencilla que son los archivos de texto.
La ventaja de los archivos de texto es que pueden ser leídos y generados desde cualquier editor de textos, no tienen formatos adicionales. La principal  desventaja es que no puedo acceder a un dato específico en el archivo, para encontrar un dato se debe leer todo el archivo (o por lo menos, todos los datos anteriores del archivo) Por esta razón se llaman archivos de acceso secuencial: Se debe leer o escribir todo el archivo completo hasta llegar al dato que me interesa.

Veamos el siguiente programa, que genera y muestra por pantalla los números primos menores que 10000:

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    int n,i;
    int max;
    int t=2;
    bool primo;
    cout<<2 <<"   "<<3<<"   ";
    n=5;    //Imprime directamente el 2 y el 3, empieza a buscar primos a partir de 5
    do
    {
        i=3;
        primo = true;
        max=sqrt(n);
        while ( i<=max)
        {
            if (n%i==0)
            {
                primo=false;
                i=n;     //En cuanto encuentra un divisor, sale del ciclo
            }
            i+=2;   //Si sólo considero los impares, no necesito probar con divisores pares
        }
        if (primo)
        {
            t++;
            cout<<n<<"   ";
            if (t==5)   //Uso t para que cada 5 números, imprima un salto de línea
            {
                t=0;
                cout<<endl;
            }
        }
        n=n+2;  //Luego del 2, sólo los impares pueden ser primos
    }
    while (n<10000);
    return 0;
}

Supongamos que quiero guardar los números primos generados en un archivo. El C++ maneja los archivos de texto como flujos de entrada y salida de caracteres. 
Para trabajar con estos objetos, se debe incluir el archivo <fstream>. Para este ejemplo, se debe generar un flujo de salida, al que llamaremos ArchSalida, y se lo debe vincular con un archivo físico en el disco. esto se hace con la siguiente instrucción: 

ofstream ArchSalida ("primos.txt",ios::out);

Esta instrucción genera un objeto de tipo ofstream llamado ArchSalida (de la misma manera que se definen las variables) con dos parámetros: El primero es un string conteniendo el nombre del archivo que se va a crear ("primos.txt"). El segundo parámetro (ios::out) indica que se crea un archivo nuevo y se va a escribir en el mismo. Si el archivo ya existía previamente, lo borra y empieza a escribir desde el inicio.

Una vez hecho esto, se puede trabajar con el archivo de la misma manera que el cout usa para trabajar con la pantalla. Si la instrucción cout << n; envía el valor de n a la salida estándar (la pantalla); la instrucción ArchSalida << n; envía el mismo valor al archivo vinculado al flujo ArchSalida. Modificando el programa anterior para que además de mostrar los números por pantalla los guarde en un archivo, queda de la siguiente manera:

#include <iostream>
#include <cmath>
#include <fstream>   //Necesario para manejar archivos
using namespace std;

int main()
{
    int n,i;
    int max;
    int t=2;
    bool primo;
    ofstream ArchSalida ("primos.csv",ios::out); //Defino un archivo de salida
    cout << 2 <<"   "<<3<<"   ";
    ArchSalida<< 2 <<"   "<<3<<"   "; //Escribo en el archivo
    n=5;
    do
    {
        i=3;
        primo = true;
        max=sqrt(n);
        while ( i<=max)
        {
            if (n%i==0)
            {
                primo=false;
                i=n;    
            }
            i+=2;   
        }
        if (primo)
        {
            t++;
            cout<<n<<"   ";
            ArchSalida<<n<<"   "; //Escribo en el archivo
            if (t==5)   
            {
                t=0;
                cout<<endl;
                ArchSalida<<endl; //Escribo en el archivo
            }
        }

        n=n+2;  
    }
    while (n<10000);
    return 0;
}

Este programa genera el archivo "primos.txt" que está en la misma carpeta que el programa y que contiene todos los números primos hasta 10.000.

Un formato de archivos muy útil para compartir información entre diferentes programas es el de valores separados por comas (csv).  Este formato es un archivo de texto en el que entre dato y dato se coloca un punto y coma. Este formato puede ser entendido por numerosos programas, Si cambiamos el nombre del archivo a "primos.csv" y escribimos un punto y coma en lugar de los espacios entre cada número, el archivo generado podrá ser leído sin problemas por cualquier planilla de cálculo, por ejemplo Microsoft Excel. Esta es una forma rápida de genera con nuestro programa datos que serán luego utilizados por otras aplicaciones.

#include <iostream>
#include <cmath>
#include <fstream>   //Necesario para manejar archivos

using namespace std;

int main()
{
    int n,i;
    int max;
    int t=2;
    bool primo;
    ofstream ArchSalida ("primos.csv",ios::out); //Defino un archivo de salida
    cout<<2 <<"   "<<3<<"   ";
    ArchSalida<<2 <<";"<<3<<";"; //Escribo en el archivo
    n=5;
    do
    {
        i=3;
        primo = true;
        max=sqrt(n);
        while ( i<=max)
        {
            if (n%i==0)
            {
                primo=false;
                i=n;     
            }
            i+=2;  
        }
        if (primo)
        {
            t++;
            cout<<n<<"   ";
            ArchSalida<<n<<";"; //Escribo en el archivo
            if (t==5)  
            {
                t=0;
                cout<<endl;
                ArchSalida<<endl; //Escribo en el archivo
            }
        }
        n=n+2;  
    }
    while (n<10000);
    return 0;
}

Se debe tener en cuenta que el programa mantendrá el archivo abierto (y bloqueado) hasta que termine de ejecutarse, impidiendo a otras aplicaciones el acceso al mismo. Si se necesita usar el archivo desde otro programa antes de que este finalice, se debe cerrar el archivo, con la función close().

ArchSalida.close();

Una vez ejecutada esta instrucción, se finaliza la escritura en el archivo, que ya queda liberado para otras aplicaciones.


No hay comentarios:

Publicar un comentario