Programmieraufgabe:

Eine Textdatei mit folgendem Aufbau enthält komplexe Zahlen:
Die erste Zeile enthält die Anzahl der Datensätze.
Eine reguläre Zeile (ein Datensatz) beginnt mit einem Bezeichner der Form z##, wobei ## eine zweiziffrige Zahl im Bereich 01 bis 99 ist. Dann folgt, durch genau ein Zwischenraumzeichen getrennt, ein Buchstabe, der die Darstellung der Zahl kennzeichnet. K steht für Komponentenform, P für Polarform. Anschließend folgen, wieder durch Zwischenraumzeichen getrennt, zwei Gleitkommazahlen, die entweder Real- und Imaginärteil der Zahlen, oder den Betrag und den Winkel in Grad bedeuten.
Beispiel für eine Datei:

4
z01 K 2.00 -4.00
z02 K -2.00 0.00
z04 P 1.00 45.00
z05 P 
2.00 135.00
  1. Deklariere mittels typedef einen Datentyp für einen Datensatz, wie oben beschrieben.
  2. Die Datei soll gelesen werden. Nach dem Lesen der ersten Zeile ist für einen Vektor, der dann die Datensätze enthalten soll, dynamisch Speicherplatz zu reservieren. Der Dateiname ist das Argument beim Programmaufruf. Fehlt dieses Argument, so ist nach dem Dateinamen zu fragen.
  3. Zur Kontrolle sollen die im Vektor abgelegten Datensätze am Bildschirm ausgegeben werden.
  4. Ein bestimmte komplexe Zahl soll anhand ihrer Bezeichnung in der Liste gefunden werden.
  5. Eine Funktion soll für eine Zahl eine Darstellung (P, K) in die andere Darstellung (K, P) umwandeln.
  6. Einfache und trotzdem komfortable Testumgebung zu den Aufgaben 2 (3) bis 5.

Loesung

/* komplexzahlen3.c
   Loesung einer Pruefungs- (Uebungs)aufgabe */

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

typedef struct {
  char name[4];
  char typ;
  double a, b;
} t_zahl;


int liesdatei (char *filename ,t_zahl **pz );
void ausgabe (t_zahl z[], int n ,int i);
void change (t_zahl *z);
int datensatzsuchen (t_zahl z[], int n, char *s);
int main (int argc, char *argv[]);

/* Lesen der Datensaetze von der Datei, ohne jede Fehlerkontrolle */
int liesdatei(char *filename, t_zahl **pz)
{
  FILE *fin;
  t_zahl *z;
  int i, n;

  while ( (fin = fopen(filename, "r")) == NULL) {
    printf("Datei nicht gefunden\n");
    filename = (char *) malloc(50);
    printf("Dateiname: ");
    scanf("%s", filename);
  }
  /* muss mit BREAK abgebrochen werden, falls nie eine Datei passt */

  fscanf(fin, "%i", &n);
  z = (t_zahl *) malloc (n*sizeof(t_zahl));

  for (i = 0; i < n; i++)
    fscanf(fin, "%s %c %lf %lf", z[i].name, &z[i].typ, &z[i].a, &z[i].b);

  fclose(fin);
  *pz = z;
  return n;
}

void ausgabe(t_zahl z[], int n, int i)
{
  if (i == -1) /* alle Datensaetze ausgeben */
  {
    printf("\n%s%s%s",
      "-------------------------\n",
      "Bez. D    Wert1   Wert2\n",
      "-------------------------\n");
    for (i = 0; i < n; i++)
      printf("%-3s  %c %8.2f %8.2f\n", z[i].name, z[i].typ, z[i].a, z[i].b);
    printf("-------------------------\n\n\n");
  }
  else         /* nur der i-te Datensatz */
    printf("(%2i) %-3s  %c %8.2f %8.2f\n", i, z[i].name, z[i].typ, z[i].a, z[i].b);
}

void change (t_zahl *z)
{
  double ac, bc;

  if (z->typ == 'K') {
    ac = z->a;
    bc = z->b;
    z->a = sqrt(ac*ac + bc*bc);
    z->b = atan2(bc, ac)*45/atan(1.0);
    z->typ = 'P';
  }
  else {
    ac = z->a;
    bc = z->b*atan(1.0)/45.0;
    z->a = ac*cos(bc);
    z->b = ac*sin(bc);
    z->typ = 'K';
  }
}


int datensatzsuchen ( t_zahl z[], int n, char *s)
{
  int i = 0;

  do {
    if (strncmp(z[i].name, s, 3) == 0) return i;
    i++;
  } while (i < n);
  return -1;
}


int main(int argc, char *argv[])
{
  t_zahl *z;   /* Zeiger auf den Vektor mit den Datensätzen */
  int n;       /* Anzahl der Datensätze */
  int i;
  char suchbez[4];

  n = liesdatei(argv[1], &z);
  ausgabe(z, n, -1);  /* alle Datensätze ausgeben */

  printf("Datensatz suchen: Ende mit suche nach einem nicht enthaltenen Datensatz!\n");
  do {
    printf("Bezeichnung (3 Zeichen) ? ");
    scanf("%3s", suchbez);
    i = datensatzsuchen(z, n, suchbez);
    if (i >= 0)
      printf("Datensatz als %2i-ter Datensatz gefunden\n", i+1);
    else
      printf("Datensatz nicht gefunden\n");
  } while (i >= 0);

  printf("\nDarstellung fuer alle Datensaetze aendern\n");
  for (i = 0; i < n; i++)
    change (&z[i]);
  ausgabe(z, n, -1);
  printf("Und nocheinmal geaendert\n");
  for (i = 0; i < n; i++)
    change (&z[i]);
  ausgabe(z, n, -1);

  return 0;
}