ThInf-HOME

  1. Einführung

  2. Beispiel einer Dateneingabe

    1. Datenein- und ausgabe für die Struktur ACCOUNT

    2. Initialisierung für die Struktur PHASE

    3. Datenein- und ausgabe für die Struktur PHASE

  3. Übungsaufgaben


I-PROGRAMMIEREN1 WS 0203 - Vorlesung mit Übung
VL11: Projekt EARTHSIMULATOR1 - Dateneingabe


AUTHOR: Gerd Döben-Henisch
DATE OF FIRST GENERATION: Dec-05, 2002
DATE OF LAST CHANGE: Dec-10, 2002
EMAIL: Gerd Döben-Henisch



1. Einführung

Nach den Vorüberlegungen aus der letzten Vorlesung zu einer möglichen Struktur der Daten für EARTHSIMULATOR1 ist es jetzt möglich, wenigstens eine Version einer Dateneingabe für den Simulator zu formulieren. Diese Eingabe wird als Eingabe über die Tastatur realisiert werden. Sollte zum Schluss des Projektes noch Zeit bleiben, soll auch eine Dateneingabe durch Angabe einer Textdatei untersucht werden.

Generell ist zu beachten, dass es sich bei allen nachfolgenden Datenstrukturen und bei dem Pogrammkode um eine rein experimentelle Version handelt, die ausschliesslich dazu dient, um verschiedene Ideen auszuprobieren (Prototyping).


START


2. Beispiel einer Dateneingabe


In den nachfolgenden Beispielen werden exemplarisch Datenstrukturen und Funktionen vorgestellt. Der gesamte Programmkode findet sich in den folgenden Dateien:


START


2.1 Datenein- und ausgabe für die Struktur ACCOUNT


Im nachfolgenden Beispiel wird angenommen, dass die Dateneingabe über geeignete Funktionen realisiert wird. Eine dieser Funktionen ist die Funktion input_data_account(struct ACCOUNT *accp, char *string). Man übergibt ihr die Adresse einer Variablen vom Typ 'struct ACCOUNT' und die zugehörige Bezeichnung als String. Dann fordert die Funktion vom Benutzer eine entsprechende Eingabe an. Das vorliegende Beispiel ist ganz einfach gehalten. Es sieht noch keinerlei Fehlerbehandlung vor. Parallel wird eine entsprechende Funktion für die Datenausgabe definiert: output_data_account(struct ACCOUNT *accp, char *string).




/************************************
 *
 * esim3_source1.c
 *
 * author: gdh
 * first: dec-09,02
 * last: -
 * idea: Hilfsfunktionen fuer esim3
 *
 **************************************************/

#include <stdio.h>
#include "esim3.h"

int input_data_account(struct ACCOUNT *accp, char *string){

  printf("\nSTARTWERT fuer %s : ",string);
  scanf("%f",&accp->sum);

  return(1);
}

int output_data_account(struct ACCOUNT *accp, char *string){

  printf("\nAKTUELLER STATUS von %s =  %.2f\n",string,accp->sum);

  return(1);
}



Um die Prototypen dieser Funktionen dem Hauptprogramm bekannt zu machen, werden Sie auch in der Headerdatei hinterlegt:




/************************************
 *
 * esim3.h
 *
 * author: gdh
 * first: dec-09,02
 * last: -
 * idea: Headerdatei zum Hauptprogramm esim3.c
 *
 **************************************************/

#define CURRENCY_STRING_LENGTH 10

struct ACCOUNT {

  float in;
  float out;
  float sum;
  float unit;
  char currency[CURRENCY_STRING_LENGTH];
};


.....
extern int input_data_account(struct ACCOUNT *, char *s); extern int output_data_account(struct ACCOUNT *, char *s);


Die somit bereitgestellten Funktionen können dann im Hauptprogramm aufgerufen werden. Nachfolgendes Beispiel zeigt, wie die Eingabefunktion input_data_account() benutzt wird, um spezielle Werte für die Kassen RK, XRA usf. einzugeben. Anschliessend wird die Funktion output_data_account() benutzt, um aaktuelle Werte aus diesen Kassen anzuzeigen.




/************************************
 *
 * esim3.c
 *
 * author: gdh
 * first: dec-09,02
 * last: -
 * idea: Demoprogramm zur Umsetzung der Anforderungen an
 *       EARTHSIMULATOR1
 *
 * compilation: gcc -o esim3 esim3.c esim3_source1.c
 * usage: esim3
 *
 **************************************************/

#include <stdio.h>
#include "esim3.h"

#define COUNTRY_PHASE_NUMBER 5

int main(void){

 /* EINRICHTEN VON KONTEN MIT DEFINIERTEM ANFANGSWERT (INITIALISIERUNG) */

  struct ACCOUNT RK = {0.0, 0.0, 0.0, 1000000.0, "Euro"};
  struct ACCOUNT XRA, AK, KK, AG;

  XRA = RK;  /* Beispiel, dass man den Wert einer Struktur an eine Variable gleicher Struktur */
  AK = RK;   /* uebergeben kann */
  KK = RK;
  AG = RK;


/*********** BEGINN DATENEINGABE SPEZIELLER STARTWERTE *************************/

printf("***** BEGINN EINGABE STARTWERTE ***** \n\n");

input_data_account(&RK, "RK");
input_data_account(&XRA, "XRA");
input_data_account(&AK, "AK");
input_data_account(&KK, "KK");
input_data_account(&AG, "AG");


/*********** AUSGABE AKTUELLER STATUS ***************************************/

printf("***** BEGINN AUSGABE AKTUELLE STATUSWERTE ***** \n\n");

output_data_account(&RK, "RK");
output_data_account(&XRA, "XRA");
output_data_account(&AK, "AK");
output_data_account(&KK, "KK");
output_data_account(&AG, "AG");

 return (1);
}




START


2.2 Initialisierung für die Struktur PHASE


Theoretisch könnte man ein Feld ('array') mit der Datenstruktur 'PHASE' genauso initialisieren wie oben die Datenstruktur 'ACCOUNT'; allerdings ist die Datenstruktur schon so umfangreich, dass diese sehr unübersichtlich würde (siehe zur Erinnerung nachfolgendes Bild):



onto4
Zusätzliche Strukturierung der Phase durch Zuordnung der Untergruppen an eine weitere Struktur PAYER_PAYEE



Es wird hier daher eine eigene Initialisierungsfunktion nur für die Datenstruktur 'PHASE' definiert. Das Prinzip hinter dieser Funktion besteht darin, dass angenommen wird, dass ein bestimmtes Land (z.B. 'germany') ein Feld von mehreren Phasen darstellt. Über den Feldindex können dann die Phasen im Intervall [0,COUNTRY_PHASE_NUMBER-1] einzeln aufgerufen werden. Bei der Umsetzung dieser Idee zeigt es sich, dass es von Vorteil wäre, die Unterteilung der Altersgruppen 'feiner' zu machen, als ursprünglich im Modell vorgesehen. Das nachfolgende Beispiel zeigt die neuen Altersgruppen:




...
int init_data_phase(struct PHASE *php,int phase_number){ if(phase_number < 1) { php->interval[0] = 0; php->interval[1] = 5; printf("Kontrolle : Phasezahlen %d - %d \n", php->interval[0], php->interval[1]); } else { php->interval[0] =((phase_number-1) * 10) +6; php->interval[1] =((phase_number-1) * 10) +15; printf("Kontrolle : Phasezahlen %d - %d \n", php->interval[0], php->interval[1]); }
...



Kontrolle : Phasezahlen 0 - 5
Kontrolle : Phasezahlen 6 - 15
Kontrolle : Phasezahlen 16 - 25
Kontrolle : Phasezahlen 26 - 35
Kontrolle : Phasezahlen 36 - 45
Kontrolle : Phasezahlen 46 - 55
Kontrolle : Phasezahlen 56 - 65
Kontrolle : Phasezahlen 66 - 75
Kontrolle : Phasezahlen 76 - 85
Kontrolle : Phasezahlen 86 - 95

 

Der folgende Text zeigt beispielhaft einen weiteren Ausschnitt aus der Initialisierungsfunktion. Die übrigen Elemente werden ganz analog initialisiert:




php->number = 0;
  php->percentage_men = 0.0;
  php->percentage_women = 0.0;
  php->birthrate = 0.0;

  php->self_employed.percentage_of_number = 0.0;
php->self_employed.actual_yearly_income = 0.0;
php->self_employed.last_yearly_income = 0.0;
php->self_employed.former_yearly_income = 0.0;
php->self_employed.RK_payment = 0.0;
php->self_employed.RK_income = 0.0;
php->self_employed.AK_payment = 0.0;
php->self_employed.AK_income = 0.0;
php->self_employed.KK_payment = 0.0;
php->self_employed.KK_income = 0.0;
php->self_employed.XRA_payment = 0.0;
php->self_employed.XRA_income = 0.0;
php->self_employed.AG_payment = 0.0;
php->self_employed.AG_income = 0.0;



Der Aufruf der Initialisierungsfunktion für die Phasen im Hauptprogramm sieht wie folgt aus:




   /********* INITIALISIERUNG DER PHASEN DURCH INITIALISIERUNGSFUNKTION *********/

 for( i=0; i<COUNTRY_PHASE_NUMBER; i++) init_data_phase(&germany[i],i);




START


2.3 Datenein- und ausgabe für die Struktur PHASE


Zusätzlich zur Initialisierungfunktion benötigt man natürlich auch eine Eingabefunktion für spezielle Werte von PHASE. Im folgenden wird ein Teil solch einer Funktion vorgestellt. Es wird eine Eingabe für die ersten Elemente aus der erweiterten Struktur PHASE (siehe unten) realisiert.

   
 struct PHASE {

  unsigned int interval[2];
  float number;
  float percentage_men;
  float percentage_women;
  float birthrate;
  float deathrate;
  float migration_plus;
  float migration_minus;
  struct PAYER_PAYEE self_employed;
  struct PAYER_PAYEE employed;
  struct PAYER_PAYEE unemployed;
  struct PAYER_PAYEE education;
  struct PAYER_PAYEE retired_persons1;
  struct PAYER_PAYEE retired_persons2;
  struct PAYER_PAYEE sick_persons;
};
   
 

Die Struktur der nachfolgenden Eingabe ist so aufgebaut, dass zunächst der bisherige Wert angezeigt wird (zu Beginn der Initialisierungswert), dann wird ein neuer Wert mit fgets() abgefragt, dieser Wert wird mittels der Funktion atof() von einer Zeichenkette in eine Float-Zahl umgewandelt. Dann wird der neue Wert zur Kontrolle nochmals ausgegeben.

  


int input_data_phase(struct PHASE *php,int phase_number){

  char input[50];

  printf("\n\n********* BEGINN EINGABE SPEZIELLER STARTWERTE FUER PHASE  *******************\n\n");
  printf("Phasezahlen %d - %d \n", php->interval[0], php->interval[1]);

  printf("\n\n*****************************************************************************\n\n");
  printf("PHASE:  Anzahl Mitglieder (Vorher) = %f\n",php->number);

  printf("\nPHASE: Anzahl Mitglieder  = ");

  fgets(input,INPUT_LENGTH-1,stdin);

     php->number = atof(input);

  printf("PHASE:  Anzahl Mitglieder Neu = %f\n",php->number);

  /**********************************************************************************/

  printf("\nPHASE: Proz-Maenner Vorher (Gleitkomma) = %f", php->percentage_men);
  printf("\nPHASE: Proz-Maenner (Gleitkomma) = ");


  fgets(input,INPUT_LENGTH-1,stdin);
     php->percentage_men = atof(input);

  printf("PHASE:  Proz-Maenner Neu = %f\n",php->percentage_men);


  /**********************************************************************************/


  printf("\nPHASE: Proz-Frauen Vorher (Gleitkomma) = %f ",php->percentage_women);
  printf("\nPHASE: Proz-Frauen (Gleitkomma) = ");
 fgets(input,INPUT_LENGTH-1,stdin);
  php->percentage_women = atof(input);
  printf("PHASE:  Proz-Frauen Neu = %f\n",php->percentage_women);



  /**********************************************************************************/

  printf("\nPHASE: Geburtenrate (Gleitkomma) = %f ",php->birthrate);
  printf("\nPHASE: Geburtenrate (Gleitkomma) = ");
 fgets(input,INPUT_LENGTH-1,stdin);
  php->birthrate = atof(input);
  printf("PHASE:  Geburtenrate Neu = %f\n",php->birthrate);



  /**********************************************************************************/

  printf("\nPHASE: Sterberate (Gleitkomma) = %f ",php->deathrate);
  printf("\nPHASE: Sterberate (Gleitkomma) = ");
 fgets(input,INPUT_LENGTH-1,stdin);
  php->deathrate = atof(input);
  printf("PHASE:  Sterberate Neu = %f\n",php->deathrate);



  /**********************************************************************************/

  printf("\nPHASE: Zuwanderung (Gleitkomma) = %f ",php->migration_plus);
  printf("\nPHASE: Zuwanderung (Gleitkomma) = ");
 fgets(input,INPUT_LENGTH-1,stdin);
  php->migration_plus = atof(input);
  printf("PHASE: Zuwanderung  Neu = %f\n",php->migration_plus);


  /**********************************************************************************/

  printf("\nPHASE: Abwanderung (Gleitkomma) = %f ",php->migration_minus);
  printf("\nPHASE: Abwanderung (Gleitkomma) = ");
 fgets(input,INPUT_LENGTH-1,stdin);
  php->migration_minus = atof(input);
  printf("PHASE: Abwanderung  Neu = %f\n",php->migration_minus);


  /**********************************************************************************/

  return(1);
}

  
  


Nachdem auf diese Weise ein erster Weg aufgezeigt ist, wie man prinzipiell Daten in das Modell eingeben kann, seien hier noch zwei Ausgabefunktionen vorgestellt. Die Funktion output_data_phase_head() zeigt nur die allgemeinen Werte einer PHASE (Anzahl, Proz.Männer, Proz.Frauen usw), während die Funktion output_data_phase() alle Werte von PHASE anzeigt.



 
int output_data_phase_head(struct PHASE *php,int phase_number){

  printf("\n\n********* PHASE ZAHLEN *******************\n\n");
  printf("Phasezahlen %d - %d \n", php->interval[0], php->interval[1]);

  printf("\n********* PHASE ZAHLEN *******************\n\n");

  printf("PHASE number = %.2f \n", php->number);
  printf("PHASE percentage_men = %.2f \n", php->percentage_men );
  printf("PHASE percentage_women  = %.2f \n",php->percentage_women );
  printf("PHASE birthrate  = %.2f \n",php->birthrate );
   printf("PHASE deathrate  = %.2f \n",php->deathrate);
   printf("PHASE migration_plus  = %.2f \n",php->migration_plus);
   printf("PHASE migration_minus  = %.2f \n",php->migration_minus);

   return(1);
}
 
 

Nachfolgend ein Ausschnitt aus einer globalen Output-Funktion für PHASE:





int output_data_phase(struct PHASE *php,int phase_number){

  printf("\n\n********* PHASE ZAHLEN *******************\n\n");
  printf("Phasezahlen %d - %d \n", php->interval[0], php->interval[1]);

  printf("\n********* PHASE ZAHLEN *******************\n\n");

  printf("PHASE number = %.2f \n", php->number);
  printf("PHASE percentage_men = %.2f \n", php->percentage_men );
  printf("PHASE percentage_women  = %.2f \n",php->percentage_women );
  printf("PHASE birthrate  = %.2f \n",php->birthrate );
   printf("PHASE deathrate  = %.2f \n",php->deathrate);
   printf("PHASE migration_plus  = %.2f \n",php->migration_plus);
   printf("PHASE migration_minus  = %.2f \n",php->migration_minus);

  printf("PHASE self_employed.percentage_of_number  = %.2f \n", php->self_employed.percentage_of_number );
printf("PHASE self_employed.actual_yearly_income  = %.2f \n", php->self_employed.actual_yearly_income );
printf("PHASE self_employed.last_yearly_income  = %.2f \n", php->self_employed.last_yearly_income );
printf("PHASE self_employed.former_yearly_income  = %.2f \n", php->self_employed.former_yearly_income );
printf("PHASE self_employed.RK_payment  = %.2f \n", php->self_employed.RK_payment );
printf("PHASE self_employed.RK_income  = %.2f \n", php->self_employed.RK_income );
printf("PHASE self_employed.AK_paymen  = %.2f \n", php->self_employed.AK_payment );
printf("PHASE self_employed.AK_income  = %.2f \n", php->self_employed.AK_income );
printf("PHASE self_employed.KK_paymen  = %.2f \n", php->self_employed.KK_payment );
printf("PHASE self_employed.KK_income  = %.2f \n", php->self_employed.KK_income );
printf("PHASE self_employed.XRA_payment   = %.2f \n", php->self_employed.XRA_payment );
printf("PHASE self_employed.XRA_income  = %.2f \n", php->self_employed.XRA_income );
printf("PHASE self_employed.AG_payment  = %.2f \n", php->self_employed.AG_payment );
printf("PHASE self_employed.AG_income  = %.2f \n", php->self_employed.AG_income );
  
....


Diese Vorschläge zur Dateneingabe können mehrfach optimiert werden. Auf zwei besonders wichtige Varianten sei aufmerksam gemacht: (i) Man kann die gesamten Daten in einer Textdatei vorhalten und sämtliche Zugriffe über diese Datei abwickeln; (ii) man kann eine Datenbankschittstelle vorsehen und die Daten von vornherein in einer Datenbank ablegen.

In beiden Fällen wird es sinnvoll sein, flexible Masken sowohl für die Eingabe wie auch für die Ausgabe bereitzustellen, so dass der Benutzer sich immer nur mit den Daten beschäftigen muss, die ihn aktuell tatsächlich interessieren.


START


3. Übungsaufgaben

  1. Bilden sie ein Team von max.3 Mitgliedern


  2. Erstellung Sie gemeinsam einen Text mit Namen und Matr.Nr. der AutorenInnen. Abgabe einer Kopie des Textes an den Dozenten vor Beginn der Vorlesung am Di (1 Woche nach Aufgabenstellung). Falls die Aufgabe ausführbaren Programmcode enthält wäre die zusätzliche Übergabe des Quelltextes auf Diskette oder per email wünschenswert. Im Falle von Programmcode muss im Programmtext auch nochmals Name und Matr.Nr. erscheinen.


  3. Präsentation der Lösung als Team vor der gesamten Gruppe. Präsentationszeit (abhängig von der Gesamtzahl der Teams) 3-5 Min. Mögliche Punkte: 1-3 im Normalfall. (Im Falle von mehr als 1 Autor ist die ausführliche Besprechung in der Übung Voraussetzung für die Vergabe der Punkte!)


  4. Versuchen Sie in dem Text Antworten auf folgende Aufgaben zu formulieren:


  5. Beschreiben Sie, ausgehend von der vorgestellten Datenstruktur und der möglichen Dateneingabe, wie die Berechnung des Nachfolgejahres möglich sein könnte. Beschränken Sie sich dabei auf die Elemente number; percentage_men; percentage_women; birthrate; deathrate; migration_plus; migration_minus; aus der Struktur PHASE.



START