/***************************************************************************
 *   Copyright (C) 2005 by Christian Bucher                                *
 *   christian.bucher@amadyne.net                                          *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

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

/*

Der Arrayindex unterliegt in C keiner Gültigkeitsprüfung, deshalb kann lesend und
schreibend(!) sif beliebige Adressen zugegriffen werden. Diesen Effekt nennt man 
Buffer Overflow. Buffer overflows können zu sporadischen Fehlfunktionen, 
Programmabstürzen und sogar zur Ausführung fremden Codes führen (Exploit).
Dieser Gefahr ist in ANSI-C nicht zu begegnen, es hilft nur die Wahl einer besser
Programmiersprache.

Die Zahlenwerte enthalten durch ein Komma statt des Dezimalpunktes. Dieses muss
muss vor der Umwandlung in eine Zahl durch den von C erwarteten Punkt konvertiert 
werden.

Die Beschränkung auf 1000 Werte ermöglicht die Verwendung eines statisch 
initialisierten Arrays.
 
Minimum und Maximum werden über einen Vergleich sämtlicher Arrayelemente mit 
einem Gleitenden Schätzwert gefunden. Die Streubreite ist die Differenz von 
Maximum und Minimum.

Die Standardabweichung berechnet sich als Wurzel der gewichteten Summe der 
Fehlerquadrate   

Die Klasseneinteilung erfolgt in 10% Schritten.
*/

#define FILE_PATH   "/home/cbx/FH/SE_2004/src/Feuchte.txt"
#define MAX_FEUCHT  1000 
#define NUM_CLASSES 10
#define FULL_RANGE  100

// Anleige aus der Übung
double arrayMin   (double *pnArray, int nLines);
double arrayMax   (double *pnArray, int nLines);
double arrayMean  (double *pnArray, int nLines);
double arrayWidth (double *pnArray, int nLines);
double arrayStdDev(double *pnArray, int nLines);

void   arrayShow        (double *pnArray, int nLines);
void   arrayClassesShow (double *pnArray, int nLines);


// Das File wird in main() abgehandelt
int main(int argc, char *argv[])
{
FILE    *fh;
double  adftFeuchten[MAX_FEUCHT];
char    szTemp[128]; // wird bei diesem File klappen
int     i, nLines = 0;
int r;

  fh = fopen(FILE_PATH,"r");
  
  if (fh)
    {
    for (nLines = 0; !feof(fh); nLines++)
      {
      // hihihi: Erst einen String einlesen...
      fscanf(fh, "%s", szTemp);
      
      // aus allen Beistrichen werden Pünkte...
      for (i = 0; szTemp[i]; i++)
        {
        if (',' == szTemp[i])
          szTemp[i] = '.';
        }
      printf("%s\n",szTemp);
      
      // und jetzt: Zahlen
      sscanf(szTemp, "%lf", &adftFeuchten[nLines]); 
      }         
    fclose (fh);
    
    arrayShow(adftFeuchten, nLines);
    
    // jetzt zur Aufbereitung:
    printf("\nAuswertung:\n\n");
    printf("Minimum:     %2.2f, Maximum:     %2.2f\n", arrayMin(adftFeuchten, nLines), arrayMax(adftFeuchten, nLines));
    printf("Mittelwert: %2.2f, Streubreite: %2.2f\n", arrayMean(adftFeuchten, nLines), arrayWidth(adftFeuchten, nLines));
    printf("Standardabweichung: %2.2f\n\n", arrayStdDev(adftFeuchten, nLines));
    printf("Klasseneinteilung:\n");
    arrayClassesShow (adftFeuchten, nLines);
    
    }
  else
    {
    printf ("Mit dem File wurde Scheisse gebaut. (fopen failed)\n");
    }
  
  return EXIT_SUCCESS;
}

// ******************************************************************************
void   arrayShow(double *pnArray, int nLines)
{
int i;

  for (i=0; i < nLines; i++)
    {
    printf("%2.2f", pnArray[i]);
    
    if (7 == (i%8))
      printf("\n");
    else
      printf("\t");
    }
    
  printf("\n");

}

double arrayMin(double *pnArray, int nLines)
{
double dftMin;
int    i;

  for (i=0, dftMin= pnArray[0]; i < nLines; i++)
    {
    if ( pnArray[i] < dftMin )
      dftMin = pnArray[i];
    }
  return dftMin; 
}

double arrayMax(double *pnArray, int nLines)
{
double dftMax;
int    i;

  for (i=0, dftMax= pnArray[0]; i < nLines; i++)
    {
    if ( pnArray[i] > dftMax )
      dftMax = pnArray[i];
    }
  return dftMax; 
}


double arrayMean(double *pnArray, int nLines)
{
double dftSum;
int    i;

  for (i=0, dftSum = 0.0; i < nLines; i++)
    {
    dftSum += pnArray[i];
    }
  return dftSum / (double)nLines; 
}


double arrayWidth(double *pnArray, int nLines)
{
  return arrayMax(pnArray, nLines) - arrayMin(pnArray, nLines); 
}

double arrayStdDev(double *pnArray, int nLines)
{
double dftSqSum, dftMean;
int    i;

  dftMean = arrayMean(pnArray, nLines);

  for (i=0, dftSqSum = 0.0; i < nLines; i++)
    {
    dftSqSum += pow (pnArray[i]-dftMean, 2);
    }

  return sqrt(dftSqSum / (double)nLines);
}

void   arrayClassesShow (double *pnArray, int nLines)
{
int    anClasses[NUM_CLASSES];
int    i, c;
register double dftTemp, dftrLow, dftrHi;


  // Zaehlerarray nullen
  for (c = 0; c < NUM_CLASSES; c++)
    anClasses[c] = 0;
    
  // und jetzt das Array ganz gefinkelt...  
  for (i = 0; i < nLines; i++)
    {
    // zwischenspeichern
    dftTemp = pnArray[i];
    
    for (c = 0, dftrLow = 0.0, dftrHi = FULL_RANGE/NUM_CLASSES; 
         c < NUM_CLASSES; 
         c++, dftrLow = dftrHi, dftrHi += FULL_RANGE/NUM_CLASSES)
      {
      if (dftTemp >= dftrLow && dftTemp < dftrHi)
        {
        anClasses[c]++;
        }
      }
    }
  
  // ausgeben 
  for (c = 0; c < NUM_CLASSES; c++)
    {
    printf("%02d-%2d|", c*10, (c+1)*10);
    }
    
  printf("\n");
  
  for (c = 0; c < NUM_CLASSES; c++)
    {
    printf(" %3d |", anClasses[c]);
    }
  
  printf("\n");

}

syntax highlighted by Code2HTML, v. 0.9.1