Adressverwaltung



  • Hallo! Da wir, wie es der Zufall so will, die gleiche Aufgabe haben, mogel ich mich mal hier mit rein 😃

    #include <stdio.h>
    #include <stdlib.h>
    
    #define BUFLEN 100 
    
    struct datensatz {
        struct datensatz *vorgaenger, *nachfolger;
        char *name, *vorname, *strasse, *hausnummer, *stadt;
        unsigned char plz[5];
    };
    
    int ordnung(struct datensatz *a, struct datensatz *b){
    
        int i=0,j=0,ges_len,a_len,b_len,result; 
    
        //Länge des kleineren Strings wird festgestellt und in ges_len deklariert
    
        for (j=0; j < BUFLEN; j++) 
        { 
            if (a->name[j] == '\0') a_len=j; 
        } 
    
        for (j=0; j < BUFLEN; j++) 
        { 
            if (b->name[j] == '\0') b_len=j; 
        } 
    
        if(a_len > b_len) 
        { 
            ges_len = b_len;  
        } 
    
        else 
        { 
            ges_len = a_len;  
        } 
    
        //Untersuchung des Namens nach lexikalische Anordnung
    
        for(i=0; i < ges_len; i++) //Es wird nur bis zur Länge des kleineren Strings gezählt
        { 
            if (a_len > b_len){
                if (a->name[i] > b->name[i]) {
                    result = -1; ges_len = i; //Fall: Buchstabe a größer b, also b steht vor a im Alphabet
                }
                else if (a->name[i] == b->name[i]) {
                    result = -1; ges_len = i; //Die untersuchten Buchstaben sind gleich,also b vor a, da a mehr Buchstaben hat              
                }
            }
    
            if (a_len < b_len){
                if (a->name[i] < b->name[i]) {
                    result = 1; ges_len = i; //Fall: Buchstabe b größer a, also b steht vor b im Alphabet
                }
                else if (a->name[i] == b->name[i]) {
                    result = 1; ges_len = i; //Die untersuchten Buchstaben sind gleich,also a vor b, da b mehr Buchstaben hat   
                }
            }
    
            if (a_len == b_len){
                if (a->name[i] > b->name[i]) {
                    result = -1; ges_len = i;
                }
                if (a->name[i] < b->name[i]) {
                    result = 1; ges_len = i;
                }
                if (a->name[i] == b->name[i]) {
                    result = 0; ges_len = i;
                }
            }
    
        } 
        return result; 
    
    }
    
    int main (int argc, const char * argv[])
    {
        struct datensatz a = {/*struct datensatz vorgänger*/,/*struct datensatz Nachfolger*/,"Mustermann","Max","Musterstrasse", "5","Musterstadt","12345"};
        struct datensatz b = {/*struct datensatz vorgänger*/,/*struct datensatz Nachfolger*/,"Mustermann","Max","Musterstrasse", "5","Musterstadt","12345"};
    
        printf("%i",ordnung(&a,&b));  
    
        return 0; 
    
    }
    

    struct datensatz ist in seiner Form, wie sie oben steht, vorgegeben.

    Ich weiß jetzt nicht wie das mit dem *vorgänger und *nachfolger realisierbar sein soll. Außerdem hab ich Probleme mit der Initialisierung von *a und *b. Wenn ich das direkt im Hauptprogramm mit gewünschten Werten initialisiere, brauche ich keine Speicherzuweisung wie malloc oder? Zudem stellt sich hier wieder das Problem mit *vorgänger und *nachfolger.

    Wäre dankbar über ein paar Tipps 🙂



  • Bei der Definition der Variablen a und b kannst du für vorgaenger und nachfolger
    NULL eintragen.

    Danach kannst du dann

    a.nachfolger = &b;
    b.vorgaenger = &a;
    

    Deine Funktion ordnung ist viel zu kompliziert.
    Zu kompliziert gedacht und zu kompliziert umgesetzt: http://www.c-plusplus.net/forum/p2285528#2285528
    Dürft ihr strcmp nutzen?
    Wenn nein, programmiere es nach.



  • Nein strcmp dürfen wir nicht benutzen, aber meine Code von Zeile 44 bis 74 macht doch das gleiche wie strcmp oder wie meinst du das?

    Ich hab da jetzt stehen:

    struct datensatz a = {NULL,NULL,"Mustermann","Max","Musterstrasse", "5","Musterstadt","12345"};
        struct datensatz b = {NULL,NULL,"Musterfrau","Max","Musterstrasse", "5","Musterstadt","12345"};
    
        printf("%i",ordnung(&a,&b));
    

    Da kommt aber leider immer 0 raus 😞



  • Dein "strcmp" ist ja auch falsch.

    Schreibe eine Funktion mystrcmp, die ganz allgemein mit char-Arrays arbeitet und nicht mit der struct.

    Du hast viel zu viel Fallunterscheidungen.

    Geh doch mal Schritt für Schritt durch deine Funktion.
    Am Besten mit dem Debugger, es geht aber auch auf dem Papier
    Da landest du bei i = 0 in Zeile 71. Was passiert dann?



  • Danke Dirk ich habe den Fehler gefunden.

    Dass das Programm mit einer Funktion vereinfacht werden sollte, ist auch ein guter Tipp, da ich nach nach Übereinstimmung des Nachnamens den Vornamen etc. vergleiche. Und das wird dann zu riesig.

    Für den Nachnamen klappt das Programm schonmal, aber wenn ich das ganze jetzt für den Vornamen weiterführe, entsteht ein komischer Fehler.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define BUFLEN 100
    
    struct datensatz {
        struct datensatz *vorgaenger, *nachfolger;
        char *name, *vorname, *strasse, *hausnummer, *stadt;
        unsigned char plz[5];
    };
    
    int ordnung(struct datensatz *a, struct datensatz *b){
    
        int i=0,j=0,ges_len,a_len,b_len,result;
    
        //Länge des kleineren Strings wird festgestellt und in ges_len deklariert
    
        for (j=0; j < BUFLEN; j++)
        {
            if (a->name[j] == '\0') a_len=j;
        }
    
        for (j=0; j < BUFLEN; j++)
        {
            if (b->name[j] == '\0') b_len=j;
        }
    
        if(a_len > b_len)
        {
            ges_len = b_len;
        }
    
        else
        {
            ges_len = a_len;
        }
    
        //Untersuchung des Namens nach lexikalische Anordnung
    
        for(i=0; i < ges_len; i++) //Es wird nur bis zur Länge des kleineren Strings gezählt
        {
            if (a_len > b_len){
                if (a->name[i] > b->name[i]) {
                    result = -1; ges_len = i; //Fall: Buchstabe a größer b, also b steht vor a im Alphabet
                }
                else if (a->name[i] == b->name[i]) {
                    result = -1; ges_len = i; //Die untersuchten Buchstaben sind gleich,also b vor a, da a mehr Buchstaben hat
                }
            }
    
            if (a_len < b_len){
                if (a->name[i] < b->name[i]) {
                    result = 1; ges_len = i; //Fall: Buchstabe b größer a, also b steht vor b im Alphabet
                }
                else if (a->name[i] == b->name[i]) {
                    result = 1; ges_len = i; //Die untersuchten Buchstaben sind gleich,also a vor b, da b mehr Buchstaben hat
                }
            }
    
            if (a_len == b_len){
                if (a->name[i] > b->name[i]) {
                    result = -1; ges_len = i;
                }
                if (a->name[i] < b->name[i]) {
                    result = 1; ges_len = i;
                }
                if (a->name == b->name) {
                    result = 0;
                }
            }
        }
    
      if (result != 0) {
            return result;
      }
    
        result = 0;
        a_len=0;
        b_len=0;
        ges_len=0;
        i=0;
        j=0;
    
        //Vorname
    
        for (j=0; j < BUFLEN; j++)
        {
            if (a->vorname[j] == '\0'){ a_len=j;} //98        
                                                        /*Hier liegt der Fehler*/
            if (b->vorname[j] == '\0'){ b_len=j;} //96
        }
    
        if(a_len > b_len)
        {
            ges_len = b_len;
        }
    
        else
        {
            ges_len = a_len;
        }
    
        //Untersuchung des Namens nach lexikalische Anordnung
    
        for(i=0; i < ges_len; i++) //Es wird nur bis zur Länge des kleineren Strings gezählt
        {
            if (a_len > b_len){
                if (a->vorname[i] > b->vorname[i]) {
                    result = -1; ges_len = i; //Fall: Buchstabe a größer b, also b steht vor a im Alphabet
                }
                else if (a->vorname[i] == b->vorname[i]) {
                    result = -1; ges_len = i; //Die untersuchten Buchstaben sind gleich,also b vor a, da a mehr Buchstaben hat
                }
            }
    
            if (a_len < b_len){
                if (a->vorname[i] < b->vorname[i]) {
                    result = 1; ges_len = i; //Fall: Buchstabe b größer a, also b steht vor b im Alphabet
                }
                else if (a->vorname[i] == b->vorname[i]) {
                    result = 1; ges_len = i; //Die untersuchten Buchstaben sind gleich,also a vor b, da b mehr Buchstaben hat
                }
            }
    
            if (a_len == b_len){
                if (a->vorname[i] > b->vorname[i]) {
                    result = -1; ges_len = i;
                }
                if (a->vorname[i] < b->vorname[i]) {
                    result = 1; ges_len = i;
                }
                if (a->vorname == b->vorname) {
                    result = 0;
                }
            }
    
        }
    
        return result;
    
    }
    
    int main (int argc, const char * argv[])
    {
        struct datensatz a = {NULL,NULL,"Mustermann","Max","Musterstrasse", "5","Musterstadt","12345"};
        struct datensatz b = {NULL,NULL,"Mustermann","Mbx","Musterstrasse", "5","Musterstadt","12345"};
    
        printf("%i",ordnung(&a,&b));
    
        return 0;
    
    }
    

    In Zeile 92 erhält der Vorname für a eine größere Länge als b, obwohl beide Vornamen gleich lang sind. Wie kann dass sein?



  • PapLoth323 schrieb:

    In Zeile 92 erhält der Vorname für a eine größere Länge als b, obwohl beide Vornamen gleich lang sind. Wie kann dass sein?

    Weil die Länge der Vornamen mit BUFLEN nichts, aber auch gar nichts zu tun hat.
    Du findest das letzte vorkommen von '\0'. Nur ist der Speicher der Vornamen da schon lange vorbei.
    Mal einen Code für strcmp, den du verstehen solltest.

    int mystrcmp(char a[], char b[])
    {
       int c = 0;
    
       while( a[c] == b[c] )  // solange die Strings gleiche Zeichen haben
       {
          if( a[c] == '\0' )  // String zu Ende, dann gleich lang (da auch b[c] \0' ist)
            return 0;
          c++;
       }
       return  ( a[c] > b[c]) ? 1 : -1;
    /* oder in lang
       if( a[c] > b[c])
          return 1;
       else
          return -1;
    */
    }
    

    Mehr ist das nicht.
    Das brauchst du einmal. Die rust du dann aus ordnung auf.
    Einmal für die Nachnamen und dann für Vornamen.
    Dann ist ordnung ein 3-Zeiler.



  • Hi! Mithilfe der Funktion ordnung kann man ja eine Funktion erstellen, die einen neuen Daten an der richtigen Stelle entsprechend der Ordnungsrelation einfügt.

    Ich weiß noch nicht so richtig wie ich die Funktion aussehen soll. Ich dachte mir in etwa struct datensatz *ordnungsrelation(struct datensatz *a,...) . Dabei weiß ich aber auch nicht, was ich als zweites Argument nehmen soll.

    Kann mir jemand paar tipps geben, wie ich dabei vorgehen muss?



  • Wenn du Daten einfügen willst, brauchst du einmal die Liste (den Anfang oder den Eintrag vor/nach dem eingetragen werden soll) und dann noch die Daten die eingefügt werden sollen.

    Bevor du jetzt versuchst das alles in der Funktion ordnung zu machen, vergiss es.
    Du brauchst erstmal Funktionen zur Listenverwaltung.



  • Ok ich habe jetzt die Funktion Ordnung, die unverändert bleibt.
    Dann benötige ich eine Funktion zur Listenverwaltung. Und zu guter Letzt die Funktion, die den neuen Datensatz einfügt, richtig?



  • DirkB schrieb:

    Du brauchst erstmal Funktionen zur Listenverwaltung.

    - Datensatz neu anlegen
    - einfügen von Daten
    - löschen von Daten
    - suchen von Daten



  • DirkB schrieb:

    DirkB schrieb:

    Du brauchst erstmal Funktionen zur Listenverwaltung.

    - Datensatz neu anlegen
    - einfügen von Daten
    - löschen von Daten
    - suchen von Daten

    Wo werden die neuen Datensätze eingespeichert, wenn ich sie einfüge. Nehmen wir mal an, ich habe schon 5 Datensätze und ich füge jetzt noch weitere ein. Wo befinden die sich?



  • Wie hast du denn die anderen 5 angelegt?

    Es geht hier doch um doppelt verkettete Listen.
    Die macht man erst, nachdem man etwas über dynamischen Speicher gelernt hat.
    Dynamischen Speicher bekommt man mit malloc und dgl. ⚠ free gehört auch dazu.

    Und man fängt mit einer leeren Liste an.
    Du kannst ja mal die (Unter-)Forensuche bemühen.



  • Danke DirkB

    Ich habe hier jetzt erstmal die Funktion für das Sortieren

    struct datensatz {
        struct datensatz *vorgaenger, *nachfolger;
        char *name, *vorname, *strasse, *hausnummer, *stadt;
        unsigned char plz[5];
    }adrliste[1000];
    
    int anzahl, aktuell;
    
    void sortDat();
    
    void sortDat()
    {
        int i, x, j;
        struct datensatz *temp;
        temp = malloc((sizeof(struct datensatz *)*1000));
    
        for(j=0;j<(anzahl+1);++j)
        {
            for(i=anzahl; i>-1; --i)
            {
                x=ordnung (&adrliste[i], &adrliste[i-1]);
                if ((x==0)||(x>0))
                {
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
                else
                {
                    *temp=adrliste[i];
                    adrliste[i]=adrliste[i-1];
                    adrliste[i-1]=*temp;
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
            }
        }
    }
    

    Ist der Code richtig?

    free würde ich dann in main einbauen.



  • ComCd schrieb:

    Danke DirkB

    Ich habe hier jetzt erstmal die Funktion für das Sortieren

    struct datensatz {
        struct datensatz *vorgaenger, *nachfolger;
        char *name, *vorname, *strasse, *hausnummer, *stadt;
        unsigned char plz[5];
    }adrliste[1000];
    
    int anzahl, aktuell;
    
    void sortDat();
    
    void sortDat()
    {
        int i, x, j;
        struct datensatz *temp;
        temp = malloc((sizeof(struct datensatz *)*1000));
        
        for(j=0;j<(anzahl+1);++j)
        {
            for(i=anzahl; i>-1; --i)
            {
                x=ordnung (&adrliste[i], &adrliste[i-1]);
                if ((x==0)||(x>0))
                {
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
                else
                {
                    *temp=adrliste[i];
                    adrliste[i]=adrliste[i-1];
                    adrliste[i-1]=*temp;
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
            }
        }
    }
    

    Ist der Code richtig?

    free würde ich dann in main einbauen.

    Ob Dein "Sortieralgorithmus" funktioniert, habe ich jetzt nicht überprüft. Aber Dein Code macht auf mich keinen sinnvollen Eindruck.

    1. Eine Funktionsdeklaration direkt vor der Definition macht keinen Sinn. Da eine Defionition auch gleichzeitig eine Deklaration ist.
    2. In C sollte man auch gleich 'nen Prototypen schreiben statt nur einer einfachen Deklaration. Wenn eine Funktion keine Parameter erwartet, schreibt man dies mit dem Schlüsselwort void. In C++ ist das nicht erforderlich.
    3. Wozu forderst Du für Dein Temp Platz für 1000 Zeiger an, wenn Du aber einen Datensatz benutzten willst?
    4. Wozu machst Du eine doppelt verkette Liste, wenn Du das eh in einem Array gespeichert hast?

    Doppelt verkette Listen macht man nicht aus Jux und Dollerei sondern dann, wenn ein Array nicht möglich ist, weil es z.B. zuviele Datensätze sind.



  • Du solltest schon mit Hilfe der vorgaenger und nachfolger Einträge durch die Liste gehen.
    Sonst sind diese Überflüssig.

    Vermeide globale Variablen.



  • Ist es so besser?

    void sortDat()
    {
        int i, x, j;
        struct datensatz *temp;
        temp = malloc((sizeof(struct datensatz *)*1000));
    
        for(j=0;j<(anzahl+1);++j)
        {
            for(i=anzahl; i>-1; --i)
            {
                x=ordnung (&adrliste[i], &adrliste[i-1]);
                if ((x==0)||(x>0))
                {
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
                else
                {
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
            }
        }
    }
    


  • ComCd schrieb:

    Ist es so besser?

    void sortDat()
    {
        int i, x, j;
        struct datensatz *temp;
        temp = malloc((sizeof(struct datensatz *)*1000));
        
        for(j=0;j<(anzahl+1);++j)
        {
            for(i=anzahl; i>-1; --i)
            {
                x=ordnung (&adrliste[i], &adrliste[i-1]);
                if ((x==0)||(x>0))
                {
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
                else
                {
                    adrliste[i].nachfolger=&adrliste[i-1];
                    adrliste[i-1].vorgaenger=&adrliste[i];
                }
            }
        }
    }
    

    Hast Du alle Warnungen des Compilers deaktiviert? Und wenn nein, warum hast Du sie ignoriert? Meinst Du der Compilerhersteller hat das aus Jux und Dollerei gemacht?



  • Ohne Array.
    Du musst ohne das [ i] auskommen.

    Was soll das temp mit Platz für 1000 Zeiger auf datensatz?

    Du hast nur Zeiger auf die Datensätze. Kein Array, kein Index.

    Schreib mal eine Funktion, die zwei Zeiger auf Datensätze bekommt und diese in der Liste vertauscht.
    Die kannst du dann auch von der Sortierfunktion aufrufen.



  • Versuchs doch mal so:

    struct daten {
           char *name;
           char *vorname;
    }
    
    struct dListe {
          struct dListe *nachfolger;
          struct daten *adresse;
    }	
    
    void Listenverwaltung(struct daten *d)
    {
    struct Liste *L;
    
    Einfuegen(&l, d);
    }
    
    void Einfuegen (struct dListe **dL, struct daten *dat)
    {
    struct dListe *neu = *dL, *b;
    
    while(neu->nachfolger != NULL) {
         if(myStrCmp(neu->nachfolger->adresse->name, dat->name) >= 0)
            break;
         neu = neu->nachfolger;
    }
    
    b = malloc(sizeof(struct dListe));
    b->adresse = dat;
    b->nachfolger = neu->nachfolger;
    neu->nachfolger = b;
    return;
    }
    

    die Funktion Listenverwaltung erhält die Daten von einer funktion, die die Daten bereits in der Struktur gespeichert hat und den entsprechenden Speicher angefordert hat.
    Für eine doppelt verkettete Liste wären noch die entsprechenden Vorgaengerknoten einzufügen.



  • War noch ein Fehler drin.

    struct daten { 
           char *name; 
           char *vorname; 
    } 
    
    struct dListe { 
          struct dListe *nachfolger; 
          struct dListe *vorgaenger;
          struct daten *adresse; 
    }   
    
    void Listenverwaltung(struct daten *d) 
    { 
    struct Liste *L; 
    L = L->nachfolger = L->vorgaenger = NULL;  
    Einfuegen(&L, d); 
    } 
    
    void Einfuegen (struct dListe **dL, struct daten *dat) 
    { 
    struct dListe *neu = *dL, *b; 
    
    while(neu->nachfolger != NULL) { 
         if(myStrCmp(neu->nachfolger->adresse->name, dat->name) >= 0) 
            break; 
         neu = neu->nachfolger; 
    } 
    
    b = malloc(sizeof(struct dListe)); 
    b->adresse = dat; 
    b->nachfolger = neu->nachfolger; 
    neu->nachfolger = b; 
    neu->nachfolger->vorgaenger = b;
    return; 
    }
    

Anmelden zum Antworten