Array von Strukturen



  • Nach langen Qualen bin ich tatsächlich noch fertig geworden - vor allem Dank euch natürlich. 🙂 Vermutlich hat das Programm noch ein paar Schwächen, aber Eingabe, Ausgaben bzw. Berechnungen stimmen jetzt.

    Falls jemand Zeit und Lust hat, dann kann er ja mal schnell drüber fliegen und Hinweise zur Verbesserungen geben. Für Kritik bin ich immer offen. 😉

    Hier der komplette Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define DARLEHENSZINS 0.05
    #define GUTHABENSZINS 0.03
    #define KONTOANZ 100
    #define BANKNR
    
    typedef struct {
        unsigned int   kontoNr;              /* Kontonummer */
        double         kontoStnd;            /* Kontostand */
        double         zinsS;                /* Zinssatz */
        double         annuitaet;            /* Annuitaet */
        char           habenOderDarl;        /* Guthaben/Darlehen */
        unsigned int   laufZt;               /* Laufzeit */ 
    } Konto;
    
    int anz;
    
    int eingabe();                             /* Methode um Array mit Konten zu 
                                                fuellen */
    void ausgabe();                            /* Methode um Konto im Array wieder 
                                                auszugeben */                                               
    
    double kapZinsS(double kontoStnd, unsigned int laufZt);
    
    double darZinsS(double kontoStnd, double annuitaet);
    
    int main(int argc, char *argv[])
    {
        Konto* konten = NULL;
        int auswahl;                            /* Speicherung f¸r die Bedingung */
    
        printf("\n\t Zweites Programm in SS11, Strukturen");
        printf(" von xx");
        printf("\n\t uebersetzt am %s", __DATE__);
        printf("\n\t um %s Uhr", __TIME__);
        printf("\n\n");
    
        do {
            printf("-1- Neues Konto anlegen\n");
            printf("-2- Alle Kontodaten ausgeben\n");
            printf("-3- Programm beenden\n");
            printf("\nIhre Auswahl : ");
            scanf("%d", &auswahl);
    
            getchar();
            switch(auswahl) {
                case 1 : eingabe(&konten);
                    break;
                case 2 : ausgabe(konten,anz);
                    break;
                case 3 : printf("Programm beendet\n");
                    break;
                default: printf("Falsche Eingabe\n");
            }
        }while(auswahl <3);
    
        system("PAUSE"); 
        return 0;
    
    }
    
    int eingabe(Konto** pkonten)
    {
        int i;
        int oldsize = 0;
        Konto* konten = NULL;
    
        printf("Wieviele Konten sollen erstellt werden? ");  scanf("%i", &anz);
        konten = realloc(*pkonten, (oldsize+anz) * sizeof(Konto));
    
        for(i = oldsize; i<oldsize+anz; ++i) 
        {
            printf("Kontodaten fuer das %2i. Konto:\n", i+1);
            char art ;
            printf("Art des Kontos: ");    scanf(" %c", &art);
            konten[i].habenOderDarl = art;
            int kontostand;
            printf("G/D Betrag: ");        scanf("%i", &kontostand); 
            konten[i].kontoStnd = kontostand;
            if(art == 'g'){
            int laufzeit;
            printf("Laufzeit: ");          scanf("%u", &laufzeit);
            konten[i].laufZt = laufzeit;
            }
            if(art == 'd'){
            int ann;
            printf("Annuitaet: ");         scanf("%i", &ann);
            konten[i].annuitaet = ann;
            }
    
        }
        *pkonten = konten;
        return oldsize+anz;
    }
    
    void ausgabe(Konto* konten, int anz){
    
        int i;
    
        for(i = 0; i<anz; i++){
    
            if(konten[i].habenOderDarl == 'g')
            {
                kapZinsS(konten[i].kontoStnd, konten[i].laufZt);
                printf("\n");
            }
    
            if(konten[i].habenOderDarl == 'd')
            { 
                darZinsS(konten[i].kontoStnd, konten[i].annuitaet);
                printf("\n");
            }
        }                 
    }
    
    /* Berechnung der Kapitalanlage mit Schleife */
    double kapZinsS(double kontoStnd, unsigned int laufZt)
    {
        int i; 
    
        for(i=1; i<=laufZt; i++){
            double zins;       
            zins = kontoStnd * GUTHABENSZINS;      
            kontoStnd = kontoStnd + zins;
            printf("Jahr: %u\n", i);
            printf("Anlaufende Zinsen: %.2lf \n", zins); 
            printf("Kapital nach Zinsen: %.2lf \n", kontoStnd);         
        }
        return kontoStnd;
    }
    
    /* Berechnung der Tilgung mit Schleife */
    double darZinsS(double kontoStnd, double annuitaet)
    {
        int i;
        double zins;
        double tilgungsrate;
    
        for(i=1; i <= kontoStnd; i++){
    
            zins = kontoStnd * DARLEHENSZINS;
            tilgungsrate = annuitaet - zins;
            kontoStnd = kontoStnd - tilgungsrate;
            printf("Jahr: %u\n", i);
            printf("Zinsen: %lf \n", zins);   
            printf("Restschuld: %.lf \n", kontoStnd); 
        }
        return kontoStnd;
    }
    

    @CStoll: Falls du es sehen solltest, kannst du mir eventuell einen Tipp geben, ob man die eingabe() ohne großen Aufwand korrigieren kann, damit es mit realloc() -> oldsize richtig funktioniert. Ich hab es leider nicht so hinbekommen wie du es mir gezeigt hast und es kamen immer ganz komische Zahlen bei den Berechnungen raus.

    Danke schonmal für alle eure Hinweise und Hilfe. Ohne euch hätte ich die Aufgabe vermutlich nicht hinbekommen. 🙂 👍



  • Du solltest die alte Größe des Arrays auch als Parameter mit übergeben, damit sie das Ende der Funktion überlebt:

    int eingabe(Konto** pkonten,int oldsize)
    {
      ...
    }
    
    //in der main:
    Konto* konten = NULL;
    int size = 0;
    ...
    switch(auswahl)
    {
    case 1:
      size = eingabe(&konten, size);
      break;
    case 2:
      ausgabe(konten, size);
      break;
    ...
    }
    

    PS: Die Prototypen der Funktionen eingabe() und ausgabe() sollten nach Möglichkeit zu den später folgenden Definitonen passen, das hilft dir und dem Compiler. Und die globale Variable int anz; bringt dir auch keine Pluspunkte.



  • Ahhhhhhh was habt ihr gegen meine Überprüfung, ob malloc/realloc gefailed hat oder nicht ? :p Besonders wenn man immer wieder speicher anfordert :o



  • Danke, CStoll! Jetzt funktioniert auch das, auch wenn nur mit der globalen Variable anz. Ich krieg es ohne die globale Variable irgendwie nicht hin, bin wohl zu blöd dazu. 😃

    Jetzt bin ich richtig happy weil alles funktioniert, ich alles halbwegs verstanden habe und morgen wohl mein Testat bekomme. 🙂

    cvcv schrieb:

    Ahhhhhhh was habt ihr gegen meine Überprüfung, ob malloc/realloc gefailed hat oder nicht ? :p Besonders wenn man immer wieder speicher anfordert :o

    Ach sorry, das baue ich natürlich auch noch rein. 😉 Hab nur rumexperementiert und fand es mit CStoll´s Version etwas übersichtlicher. Ich bin noch ein Newbie und große Programmiercodes machen mir Angst... 😃 😃



  • Die Parameter-Übergabe an die Funktion ausgabe() hast du doch auch hingekriegt, so ähnlich sollte es auch bei der eingabe() funktionieren. Du mußt nur daran denken, daß die neue Arraygröße als Rückgabewert herausgegeben wird - und diesen Rückgabewert entgegennehmen.

    cvcv schrieb:

    Ahhhhhhh was habt ihr gegen meine Überprüfung, ob malloc/realloc gefailed hat oder nicht ? :p Besonders wenn man immer wieder speicher anfordert :o

    Nimm's nicht persönlich - ich bin halt C++-verwöhnt 😃
    (weißt du eigentlich, ob nach einem misslungenen realloc()-Aufruf der bisherige Speicherbereich noch gültig ist?)

    @mr unknown: Die zwei Zeilen zur Auswertung des realloc()-Ergebnisses solltest du dir aber wirklich noch gönnen.



  • CStoll schrieb:

    Die Parameter-Übergabe an die Funktion ausgabe() hast du doch auch hingekriegt, so ähnlich sollte es auch bei der eingabe() funktionieren. Du mußt nur daran denken, daß die neue Arraygröße als Rückgabewert herausgegeben wird - und diesen Rückgabewert entgegennehmen.

    cvcv schrieb:

    Ahhhhhhh was habt ihr gegen meine Überprüfung, ob malloc/realloc gefailed hat oder nicht ? :p Besonders wenn man immer wieder speicher anfordert :o

    Nimm's nicht persönlich - ich bin halt C++-verwöhnt 😃
    (weißt du eigentlich, ob nach einem misslungenen realloc()-Aufruf der bisherige Speicherbereich noch gültig ist?)

    😛 Schlimme Sache ! ^^

    Ja, er ist noch gültig, soweit ich weiss.

    If the function failed to allocate the requested block of memory, a NULL pointer is returned, and the memory block pointed to by argument ptr is left unchanged.



  • Ja, er bleibt gültig. Man muss den Zeiger aber logischerweise vorher sichern, damit er bei einem Fehler nicht mit NULL überschrieben wird.



  • CStoll schrieb:

    @mr unknown: Die zwei Zeilen zur Auswertung des realloc()-Ergebnisses solltest du dir aber wirklich noch gönnen.

    Werd ich aufjedenfall machen. Kann nicht schaden und ich lerne etwas dabei.

    P.S. Du bist anscheinend ein exzellenter Programmierer. Ich werde froh sein, wenn ich irgendwann auch nur halb so gut wie du werde. 🙂



  • mr_unknown schrieb:

    CStoll schrieb:

    @mr unknown: Die zwei Zeilen zur Auswertung des realloc()-Ergebnisses solltest du dir aber wirklich noch gönnen.

    P.S. Du bist anscheinend ein exzellenter Programmierer. Ich werde froh sein, wenn ich irgendwann auch nur halb so gut wie du werde. 🙂

    Das ist er in der Tat ^^ Immer schön weiter lernen, solange es Spass macht lernt man extrem schnell und gut.



  • Danke euch beiden 🙄



  • cvcv schrieb:

    mr_unknown schrieb:

    CStoll schrieb:

    @mr unknown: Die zwei Zeilen zur Auswertung des realloc()-Ergebnisses solltest du dir aber wirklich noch gönnen.

    P.S. Du bist anscheinend ein exzellenter Programmierer. Ich werde froh sein, wenn ich irgendwann auch nur halb so gut wie du werde. 🙂

    Das ist er in der Tat ^^ Immer schön weiter lernen, solange es Spass macht lernt man extrem schnell und gut.

    Jap, merk ich auch, dass es dann schneller geht. 🙂 Spaß macht es mir mittlerweile tatsächlich. Muss nur versuchen mehr Zeit ins Programmieren zu investieren.



  • edit: ok hat sich erledigt^^



  • Hallo, ihr habt hier super Beispiele aber ich habe eine frage ich muss ein ähnliches programm schreiben und muss das array dynamisch machen ! d.h. ich muss eine datei einlesen und danach weiß ich erst wie viele Strukturen ich haben mussen , dieses kann zwischen 1 und ca 2000 sein !gibt es da eine möglichkeit wie in dem Beispiel von euch das Konstant irgendwie dynamisch zu machen ?

    mfg bernd



  • Ich meinte KONTOANZ



  • Wo genau liegt denn dein Problem? Bei den letzten Beispielcodes wird die Konstante gar nicht mehr verwendet, sondern die Anzahl in einer Variable gespeichert.


Anmelden zum Antworten