Acerca de:

Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)

lunes, 1 de agosto de 2011

Leyendo data numérica desde un archivo de texto con C++

Tengo un archivo de texto que contiene una lista de números con el siguiente formato:


He llamado al archivo "18.txt" por ninguna razón en especial. Lo que quiero hacer es leer los números en el archivo y realizar algunas operaciones matemáticas con ellos. Como están en formato de texto, primero debo convertirlos a números decimales.
Para ello uso la función "atof", pero hay un problema: mis números usan coma decimal, y la función "atof" considera punto decimal. Debo leer los números, línea por línea, y  ponerlos en el formato con el que puede trabajar "atof", así que declaro un aray de caracteres llamado "palabra". Ninguno de los números guardados en "18.txt" ocupa más de cinco caracteres, así que "palabra" es declarada como: char palabra[6];
Luego recorro cada caracter dentro de "palabra" y si encuentro una coma, la reemplazo por un punto.

El array "beta", separa espacio en memoria para 150 números decimales ya que sólo quiero operar con 150 números en total.

El código fuente es el siguiente (el ejecutable compilado está en la misma carpeta que "18.txt"):

#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#pragma hdrstop
#pragma argsused

void main(int argc, char* argv[])
{    FILE *fp;
     int i;
     double *beta, c, promedio, rms, desviacion;
     char palabra[6];

     beta = (double *)malloc(sizeof(double)*151);
     i=0;
     fp = fopen("18.txt", "r");

if (fp==NULL)
 cout<<"no existe el archivo \n";

else {

    do
    {
       c = fscanf(fp, "%s", palabra);

       for(int j=0; j<6; j++)
       if (palabra[j]== ',')
            { palabra[j]='.' break; }
       
        beta[i] = atof(palabra);
        cout<<beta[i];
        cout<<"\n";
        i++;
    }
  while (c != EOF && i != 151);

//valores estadísticos:
promedio=0; desviacion=0; rms=0;

//Promedio
     for (int j= 0; j<=150; j++)
       promedio= promedio+ beta[j];
     
       promedio = promedio/151;

    cout<<"Promedio "; cout<<promedio;
    cout<<"\n";

//Desviación Estándar
      for (int j= 0; j<=150; j++)
       desviacion= desviacion + pow((beta[j]-promedio),2);
       
       desviacion=pow(desviacion,0.5)/pow(151,0.5);
       cout<<"la desviacion estandar es: "; cout<<desviacion;
       cout<<"\n";

//Valor Cuadrático Medio   
      for (int j= 0; j<=150; j++)
       rms= rms + pow(beta[j],2);
       
       rms=pow(rms,0.5)/pow(151,0.5);
       cout<<"El valor RMS: "; cout<<rms;
       cout<<"\n";

       fclose(fp);
    }
       system("PAUSE");
  }

Pero si quiero operar con todos los números en un archivo de texto sin importar cuántos sean, usaré este código:

#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#pragma hdrstop
#pragma argsused

void main(int argc, char* argv[])
{    FILE *fp;
     double i;
     double beta, c, promedio, rms, desviacion;
     char palabra[6];
     //valores estadísticos:
     promedio=0; desviacion=0; rms=0;

     i=0;
     fp = fopen("18.txt", "r");

if (fp==NULL)
 cout<<"no existe el archivo \n";

else {

    do
    {
       c = fscanf(fp, "%s", palabra);

       for(int j=0; j<6; j++)
       if (palabra[j]== ',')
       { palabra[j]='.'break; }
       
        beta = atof(palabra);
        cout<<beta;
        cout<<"\n";
        i++;

        promedio = promedio + beta;       
        rms = rms + pow(beta,2);

    }
  while (c != EOF);
     
    promedio = promedio/i;
    rms=pow(rms,0.5)/pow(i,0.5);

    i=0;
    rewind(fp);   

    do
    {
       c = fscanf(fp, "%s", palabra);

       for(int j=0; j<6; j++)
       if (palabra[j]== ',')
       { palabra[j]='.';  break; }
       
        beta = atof(palabra);
        i++;

        desviacion= desviacion + pow((beta-promedio),2);
    }
  while (c != EOF);

    desviacion=pow(desviacion,0.5)/pow(i,0.5);

    cout<<"Promedio "; cout<<promedio;
    cout<<"\n";
    cout<<"la desviacion estandar es: "; cout<<desviacion;
    cout<<"\n";
    cout<<"El valor RMS: "; cout<<rms;
    cout<<"\n";  

       fclose(fp);
    }
    system("PAUSE");
  }

Ambos códigos han sido probados con el compilador gratuito de Borland.
Cómo usar el compilador, lo explico aquí.

En este link hay información sobre "fscanf" y "rewind". Y aquí hay un tutorial sobre lectura y escritura de archivos con C++.