C-Programmierung: Aufgaben: Elektrische Messdaten

Aus Wikibooks
Wechseln zu: Navigation, Suche

Aufgabenstellung[Bearbeiten]

Schreiben Sie ein Programm, das eine Messdatendatei, die Strom- und Spannungswerte enthält, ausliest und daraus folgende Kennwerte für jede Größe berechnet:

  • Minimal- und Maximalwert,
  • Gleichanteil (linearer Mittelwert),
  • Effektivwert (geometrischer Mittelwert),

Der Name der Datei soll als Kommandozeilenargument übergeben werden. Über die Angabe einer Option in der Kommandozeile sollen nur die Messdaten auf dem Bildschirm ausgegeben werden. Aufrufbeispiele für das Programm sind

  • Berechnung und Ausgabe der Kennwerte: Aufgabe07.exe messdaten.txt
  • Ausgabe der Messdatenpaare: Aufgabe07.exe messdaten.txt -print

Vor der Berechnung oder Ausgabe sollen alle Messwerte eingelesen werden. Auf die Daten soll über ein Array von Zeigern, die auf jeweils ein Messdatenpaar verweisen angesprochen werden. Nach dem letzten Datenpaar soll das nachfolgende Element ein Null-Pointer sein, um das Ende zu markieren. Die Datenstruktur könnte zum Beispiel wie folgt definiert werden:

typedef struct
{
  double spannung, strom;
} Messwert;

Messwert *daten[MAX ANZAHL];

Die Berechnung und Ausgabe der Kennwerte auf dem Bildschirm soll in einer eigens definierten Funktion realisiert werden. Die Ausgabe der Messwerte soll ebenfalls durch eine Funktion erfolgen. Dabei sollen die Werte tabellarisch auf dem Bildschirm seitenweise ausgeben werden (pro Ausgabeseite 25 Zeilen). Folgende Fehlersituationen sind zu berücksichtigen:

  • Die Anzahl der Kommandozeilenargumente ist falsch.
  • Die Messdatendatei lässt sich nicht öffnen.
  • Beim Einlesen der Messdaten steht kein Speicherplatz mehr zur Verfügung.

Im Fehlerfall soll das Programm auf dem Bildschirm eine entsprechende Meldung ausgeben, ggf. bereitgestellten Speicher wieder freigeben und sich beenden.

Musterlösung[Bearbeiten]

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

/* Definition Typ Messwert */
typedef struct
{
  double spannung, strom;
} Messwert;

/* Funktions-Prototypen */
int  BerechnungAusgabe(Messwert *daten [], int start);
int  AusgabeMessdaten(Messwert *daten [], int start);
void speicherfreigabe(Messwert *daten [], int start);

int main(int argc, char *argv [])
{
  enum { MAX_ANZAHL = 700 };
  Messwert *daten[MAX_ANZAHL];    /* Array von Zeigern auf Messwert-Daten */
  FILE *fp;
  double sp, str;                 /* Hilfsvariablen Spannung, Strom*/
  int start;

  if (argc == 1)    /* Fehlerbehandlung */
  {
    fprintf(stderr, "Fehler: Geben Sie den Namen der Datei an, optional zzgl. [-print]");
    return 1;
  }

  fp = fopen(argv[1], "r");    /* Öffnen der Datei zum Lesen */

  if (fp == NULL)        /* wenn Datei nicht geöffnet werden konnte Fehlerhinweise und Ende */
  {
    fprintf(stderr, "\nFehler beim Oeffnen der Datei %s\n", argv[1]);
    return 2;
  }

  if (argc == 3)        /* Fehlerbehandlung des optionalen 2. Parameters */
  if (strcmp(argv[2], "-print") != 0)
  {
    fprintf(stderr, "\n\nder Parameter %s ist falsch", argv[2]);
    fclose(fp);
    return 3;
  }

  printf("\nDatei %s wurde zum Lesen geoeffnet!\n\n", argv[1]);

  /*
     paarweises Einlesen der Werte
     Abbruch wenn Grenze MAX_ANZAHL erreicht oder keine 2 Messwerte durch ';' getrennt zusammen gelesen werden konnten
     */
  for (start = 0; start < MAX_ANZAHL - 1 && fscanf(fp, "%lf;%lf", &str, &sp) == 2; start++)
  {
    /* Speicherplatz für Daten anfordern */
    if ((daten[start] = malloc(sizeof (Messwert))) == NULL)
    {
      fprintf(stderr, "Kein freier Speicher vorhanden.\n");
      fclose(fp);
      speicherfreigabe(daten, start);
      return 4;
    }

    /* Kopieren der Daten aus den Hilfsvariablen in den Speicher, auf die der Zeiger aktuell zeigt */
    daten[start]->strom = str;
    daten[start]->spannung = sp;
  }

  /* Datei schließen */
  fclose(fp);

  switch (argc) /* Fallunterscheidung zwischen Berechnen und Ausgaben der Reihe */
  {
  case 2:  BerechnungAusgabe(daten, start);  break;

  case 3:  AusgabeMessdaten(daten, start);   break;

  default: printf("\nIhre Eingabe wurde nicht akzeptiert, eventuell wurden zu viele Parameter eingegeben.");  break;
  }

  speicherfreigabe(daten, start);

  return 0;
}


/*
  Funktion zum Ermitteln der benötigten Daten aus der Messreihe und Berechnung
  ============================================================================
  */

int BerechnungAusgabe(Messwert *daten [], int start)
{
  const double Pi = 3.141592653;
  int i;
  double max_strom, max_spannung, min_strom, min_spannung;
  double u_gleichricht, i_gleichricht, u_effektiv, i_effektiv;

  max_strom = 0;
  max_spannung = 0;
  min_strom = 0;
  min_spannung = 100000000;

  /* Suchen von Min- und Max-Werten */

  for (i = 0; i < start; i++)
  {
    if (max_strom < daten[i]->strom)
    {
      max_strom = daten[i]->strom;
    }

    if (max_spannung<daten[i]->spannung)
    {
      max_spannung = daten[i]->spannung;
    }
    if (min_strom>daten[i]->strom)
    {
      min_strom = daten[i]->strom;
    }
    if (min_spannung > daten[i]->spannung)
    {
      min_spannung = daten[i]->spannung;
    }
  }

  /* Berechnung der einzelnen Daten */
  /* ===============================================================================================*/
  /* Berechnen des Gleichrichtwertes */
  u_gleichricht = 2 / Pi*max_spannung;
  i_gleichricht = 2 / Pi*max_strom;


  /* Berechnen des Effektivwertes */
  u_effektiv = max_spannung / sqrt(2);

  i_effektiv = max_strom / sqrt(2);

  /* Ausgabe der berechneten werte */
  /*=============================================================================================== */

  printf("\n\nDie berechneten Werte fuer ihre Messdatenreihe lauten:");

  printf("\n\n==========================================");
  printf("\n \t\t||  Strom  ||  Spannung\t||");
  printf("\n==========================================");
  /* Ausgabe Minima, Maxima */
  printf("\n maxima\t\t|| %3.3f A || %3.3f V\t||", max_strom, max_spannung);
  printf("\n==========================================");
  printf("\n minima\t\t||%3.3f A || %3.3f V\t||", min_strom, min_spannung);
  printf("\n==========================================");
  /* Ausgabe der Effektivwerte */
  printf("\n Effektivwert\t|| %3.3f A || %3.3f V\t||", i_effektiv, u_effektiv);
  printf("\n==========================================");
  /* Ausgabe der Gleichrichtwerte */
  printf("\n Gleichrichtwert|| %3.3f A || %3.3f V\t||", i_gleichricht, u_gleichricht);
  printf("\n==========================================");

  return 0;
}

int AusgabeMessdaten(Messwert *daten [], int start)
{
  int i;

  printf("\n\tSpanung || Strom\n");

  for (i = 0; i < start; i++)
  {
    printf("%4d  %8.4f  || %8.4f\n", i, daten[i]->spannung, daten[i]->strom);
  }

  return 0;
}

void speicherfreigabe(Messwert *daten [], int start)
{
  int i;
  for (i = 0; i < start; i++)
  {
    free(daten[i]);
  }
}