Löschen eines Elements aus der Liste

Dieses Thema Löschen eines Elements aus der Liste im Forum "Windows XP Forum" wurde erstellt von ripezone, 18. März 2006.

Thema: Löschen eines Elements aus der Liste hello ich hab ein->'kleines'' problem ich bin noch ziemlicher anfänger in C++ Programmierung und hab mich jetzt ein...

  1. hello
    ich hab ein->'kleines'' problem ich bin noch ziemlicher anfänger in C++ Programmierung und hab mich jetzt ein bisschen mit der einfach verketteten Liste gespielt

    Mein Porgramm:

    /*
    Programm: Einfach verkettete Liste

    Aufgaben:
                1. Einfügen am Anfang
                2. Anhängen am Ende
                3. Ausgabe am Bildschirm
                4. Einlesen von einer Datei
                5. Ausgabe in eine Datei
                6. Suchen nach Strasse
                7. Löschen nach Nachname
                8. Löschen nach Nachname
                9. Löschen nach Land
               
    */

    #include <iostream.h>
    #include <conio.h>
    #include <malloc.h>

    struct mitglied                             //Datenstruktur
    {
        char vorname[20];
        char nachname[20];
        char strasse[20];
        char land[20];
        int hausnummer;
        char kontonummer[20];
        mitglied*next;
    };

    void einfuganfg(mitglied *(*start));        //Prototyp Einfügen am Anfang
    void anhaengenende(mitglied *(*start));     //Prototyp Anhängen am Ende
    void ausgabe(mitglied *start);              //Prototyp Ausgabe am Bildschirm
    void einlesendatei(mitglied *(*start));     //Prototyp Einlesen von Datei
    void ausgabedatei(mitglied *start);         //Prototyp Ausgabe in Datei
    void suchenstrasse(mitglied *(*start));     //Prototyp Suchen nach Straße
    void suchenhausnummer(mitglied *(*start));  //Prototyp Suchen nach Hausnummer
    void loeschennachname(mitglied *(*start));  //Prototyp Löschen nach Nachname
    void loeschenland(mitglied *(*start));      //Prototyp Löschen nach Land
    void einfuganfg(mitglied *(*start))         //Unterprogramm Einfügen am Anfang
    {
        mitglied *p;                            //Hilfspointer
        char auswahl;
       
        do
        {
        p=(mitglied*)malloc(sizeof(mitglied));  //Größe des Hilfspointers bestimmen
        cout<<Vorname: ;                     //Einlesen der einzelnen geforderten Daten
        cin>>(*p).vorname;
        cout<<Nachname: ;
        cin>>(*p).nachname;
        cout<<Strasse: ;
        cin>>(*p).strasse;
        cout<<Hausnummer: ;
        cin>>(*p).hausnummer;
        cout<<Land: ;
        cin>>(*p).land;
        cout<<Kontonummer: ;
        cin>>(*p).kontonummer;
        (*p).next=*start;
        *start=p;
        cout<<Wiederholen j/n????: ;
        cin>>auswahl;
        }while(auswahl=='j');
    };
    void anhaengenende(mitglied *(*start))    //Unterprogramm Anhängen am Schluss
    {   mitglied *p;                          //Erster Hilfspointer
        mitglied *h;                          //Zweiter Hilfspointer
       
        char auswahl;
        do
        {
        h=(mitglied*)malloc(sizeof(mitglied)); 
        cout<<Vorname: ;
        cin>>(*h).vorname;
        cout<<Nachname: ;
        cin>>(*h).nachname;
        cout<<Strasse: ;
        cin>>(*h).strasse;
        cout<<Hausnummer: ;
        cin>>(*h).hausnummer;
        cout<<Land: ;
        cin>>(*h).land;
        cout<<Kontonummer: ;
        cin>>(*h).kontonummer;
        if(*start==0)                           
        {                                       
            *start=h;
            (*h).next=0;
        }
        else
        {
            p=*start;
            while((*p).next!=0)
            {
                p=(*p).next;
            }
            (*p).next=h;
            (*h).next=0;
        }
        cout<<Wiederholen j/n????: ;
        cin>>auswahl;
        }while(auswahl=='j');   
    }
    void ausgabe(mitglied *start)     //Unterprogramm Ausgabe am Bildschirm
    {   mitglied *p;                  //Hilfspointer
        p=start;
        do
        {
        cout<<Vorname: <<(*p).vorname<<\n;
        cout<<Nachname: <<(*p).nachname<<\n;
        cout<<Strasse: <<(*p).strasse<<\n;
        cout<<Hausnummer: <<(*p).hausnummer<<\n;
        cout<<Land: <<(*p).land<<\n;
        cout<<Kontonummer: <<(*p).kontonummer<<\n\n\n;
        p=(*p).next;
        }while(p!=0);
    };
    void einlesendatei(mitglied *(*start)) //Unterprogramm Einlesen von Datei
    {   
        mitglied *p;                        //Hilfspointer
        FILE*datei;                        //Filepointer
        datei=fopen(C:\\Dokumente und Einstellungen\\Admin\\Eigene Dateien\\_Schule\\_3aheli\\AINF\\auspj1.txt,r);//Datei öffnen zum Lesen
        if(datei==0)
        { cout<<datei konnte nicht geoffnet werden;
        }
        while(!feof(datei))
        {
        p=(mitglied*)malloc(sizeof(mitglied));
        fscanf(datei,%s\n,(*p).vorname);
        fscanf(datei,%s\n,(*p).nachname);
        fscanf(datei,%s\n,(*p).strasse);
        fscanf(datei,%d\n,&(*p).hausnummer);
        fscanf(datei,%s\n,(*p).land);
        fscanf(datei,%s\n,(*p).kontonummer);
        (*p).next=*start;
        *start=p;
        };
        fclose(datei);    //Datei schließen
       
    };
    void ausgabedatei(mitglied *start) //Unterprogramm Ausgabe in Datei
    {   mitglied *p;    //Hilfspointer
        FILE*datei;
        char um=10;     //Zeilenumbruch
        datei=fopen(C:\\Dokumente und Einstellungen\\Admin\\Eigene Dateien\\_Schule\\_3aheli\\AINF\\auspj1.txt,w); //Datei öffnen zum schreiben
        p=start;
        do
        {
        fputs((*p).vorname,datei);
        fputc(um,datei);
        fputs((*p).nachname,datei);
        fputc(um,datei);
        fputs((*p).strasse,datei);
        fputc(um,datei);
        fprintf(datei,%d,(*p).hausnummer);
        fputc(um,datei);
        fputs((*p).land,datei);
        fputc(um,datei);
        fputs((*p).kontonummer,datei);
        fputc(um,datei);
        fputc(um,datei);
        p=(*p).next;
        }while(p!=0);
        fclose(datei);    //Datei schließen
    };
    void suchenstrasse(mitglied *(*start))    //Unterprogramm zum Suchen nach Strasse
    {
        char strasse[20];
        mitglied *p;    //Hilfspointer
        p=*start;
        cout<<Welche Strasse wird gesucht?? ;
        gets(strasse);
        do
        {
            if(strcmp(strasse,(*p).strasse))    //Vergleich der beiden Strings
            {
            }
            else
            {
                    cout<<(*p).vorname<<\n;
                    cout<<(*p).nachname<<\n;
                    cout<<(*p).strasse<<\n;
                    cout<<(*p).hausnummer<<\n;
                    cout<<(*p).land<<\n;
                    cout<<(*p).kontonummer<<\n;
            }
           
        p=(*p).next;
        }while(p!=0);
    }
    void suchenhausnummer(mitglied *(*start))           //Unterprogramm zum Suchen nach Hausnummer
    {
        int hausnummer;
        mitglied *p;    //Hilfspointer
        p=*start;
        cout<<Welche Hausnummer wird gesucht?? ;
        cin>>hausnummer;
        do
        {
            if(hausnummer==(*p).hausnummer)    //Vergleich ob die gesuchte Hausnummer gleich der vorhandenen Hausnummer ist
            {
                    cout<<(*p).vorname<<\n;
                    cout<<(*p).nachname<<\n;
                    cout<<(*p).strasse<<\n;
                    cout<<(*p).hausnummer<<\n;
                    cout<<(*p).land<<\n;
                    cout<<(*p).kontonummer<<\n;
            }
           
        p=(*p).next;
        }while(p!=0);
    }
    void loeschennachname(mitglied *(*start))           //Unterprogramm zum Löschen nach Nachname
    {char nachname[20];
        mitglied *p;    //Erster Hilfspointer
        mitglied *h;    //Zweiter Hilfspointer     
        p=*start;
        int i=0;
        cout<<Loeschen nach Nachname?? ;
        cin>>nachname;
       
            if(strcmp(nachname,(*p).nachname))  //Vergleich der beiden Strings
            {
            }
            else
            {
              if (p == NULL)    // überprüfen, ob Liste noch leer ist
              {cout<<Liste ist leer!);   
              }
            else
            { 
         h = (*p).next; 
                                                               
         (*p).next = (*h).next;
         free (p);         
          }
                   
            }
     
    }
    void loeschenland(mitglied *(*start))        //Unterprogramm zum Löschen nach Land
    {char land[20];
    int i=0;
        mitglied *p;    //Erster Hilfspointer
        mitglied *h;    //Zweiter Hilfspointer
        p=*start;
        cout<<Loeschen nach Land?? ;
        cin>>land;
        do
        {
            if(strcmp(land,(*p).land))    //Vergleich der beiden Strings
            {
            }
            else
            {h = (*p).next;
                    (*p).next=(*h).next;
                    free(p);
                   
            }
       
        }while(p!=0);
    }

    int main()      //Hauptprogramm
    {
        mitglied*p; //Hilfspointer
        mitglied*start;    //Startpointer
        int auswahl;
        start=0;

        do
        {
        cout<<\nProgramm: Einfach verkettete Liste\n;    //Menüauswahl
        cout<<Menue: \n\t1.)Einfuegen am Anfang;
        cout<<\n\t2.)Anhaengen am Ende;
        cout<<\n\t3.)Ausgabe am Bildschirm;
        cout<<\n\t4.)Einlesen von einer Datei;
        cout<<\n\t5.)Ausgabe in eine Datei\n\t;
        cout<<6.)Suchen nach Strasse\n\t;
        cout<<7.)Suchen nach Hausnummer;
        cout<<\n\t8.)Loeschen nach Nachname;
        cout<<\n\t9.)Löschen nach Land;
        cout<<\n\t10.)Beenden;
        cout<<\nAuswahl: ;
        cin>>auswahl;
           
            switch(auswahl)            //Mehrfachauswahl für die Unterprogramme
            {
            case 1:
                    einfuganfg(&start);
                    break;
       
            case 2:
                    anhaengenende(&start);
                    break;
           
            case 3:
                    ausgabe(start);
                    break;
                   
            case 4:
                    einlesendatei(&start);
                    break;
                   
            case 5:
                    ausgabedatei(start);
                    break;
           
            case 6:
                    suchenstrasse(&start);
                    break;
                   
            case 7:
                    suchenhausnummer(&start);
                    break;
                   
            case 8:
                    loeschennachname(&start);
                    break;
                   
            case 9:
                    loeschenland(&start);
                    break;
            }
       }while(auswahl!=10);
       
    getch();
    }
    ich hab probleme beim löschen nach nachname und beim löschen nach land, das programm macht nämlich überhaupt nichts
    vl könnt ihr mir helfen
    wer echt super
    danke
     
  2. So (z.B.) müsste es funktionieren:
    In der Funktion ausgabe dies hier vor do setzen (start ohne Sternchen, unten mit):
    Code:
      if(start == 0) {
        cout << Die Liste ist leer. << endl;
      } else
    
    Code:
    // Löschen des ersten Eintrags mit dem entsprechenden Nachnamen.
    void loeschennachname(mitglied** start)   
    {
        
      if (*start == 0) {
        cout << Liste ist leer. << endl;
        return;
      }
    
      char nachname[20];  
      cout << Loeschen nach Nachname: ;
      // Unsichere Eingabe
      cin >> nachname;  
      
      mitglied* aktuell= *start;        // Erster Hilfspointer
      mitglied* nachlauf= aktuell;    // Zweiter Hilfspointer     
    
      if(!strcmp(nachname, aktuell->nachname))
        // Startzeiger auf das dem aktuellen Element folgende Element setzen (*)
        *start= aktuell->next;
      else {
        aktuell= aktuell->next;
        while(aktuell) {
          if(!strcmp(nachname, aktuell->nachname)) {
            //->next' des vorigen Elementes auf das nächste Element setzen (*)
            nachlauf->next= aktuell->next;
            break;
          }
          nachlauf= aktuell;
          aktuell= aktuell->next;
        };    
      }
    
      if(aktuell == 0)
        cout << Es wurde kein Mitglied mit dem Nachnamen \ << nachname << \ gefunden. << endl;
      else
        // Hinweis: free ist auch mit einem 0-Zeiger sicher; aber da wir hier wegen der Meldung eh abfragen ...
        free(aktuell);  
    }
    
    (*)
    Wichtig zum Verständnis: Das zu löschende Element wird damit in der Liste übersprungen, es wird also aus der Liste entfernt.

    Beispiel:

    start -> E1 -> E2 -> E3
    'aktuell' zeigt auf E2

    Das Entfernen von Element 2 aus der Liste bedeutet nun lediglich, E1.next auf E3 zu setzen.

    start -> E1 -> E3
    'aktuell' zeigt immer noch auf E2

    E2 selbst existiert aber trotzdem noch im Speicher; die Adresse von E2 befindet sich nur noch in->aktuell'. Würden wir das Element weiter unten nicht löschen (free), würde die Liste zwar korrekt funktionieren, aber es würde ein Speicherleck entstehen, da wir nicht mehr auf E2 zugreifen könnten.

    Wir verlassen die Funktion, ohne E2 zu löschen ...
    start -> E1 -> E3
    'aktuell' ruht bis zur nächsten Reinkarnation in den ewigen Bytegründen
                                   E2s letzte Worte: Es ist einsam in den endlosen Weiten des Speichers. Da draußen hört dich niemand schreien, wenn->aktuell' sich unter den Acker gemacht hat [Regieanweisung: immer leiser werdend]) (**)

    (**) Sorry, ich habe 39,1°C Fieber

    Erst beim Programmende würde der Speicher, den E2 belegt, vom Betriebssystem automatisch freigegeben.

    Noch zum Original:
    Code:
    // Hier vergleichst Du (verwendest also p) ...
    if(strcmp(nachname, (*p).nachname))
    {
    
    }
    else
    { // ... und schaust dann anschließend nach, ob p überhaupt gültig ist.
      if (p == NULL) 
      {
        cout<<Liste ist leer!);   
      }
      else {  
        h= (*p).next;  
        // Hier wird->next' von p geändert [es muss aber nicht->next' des aktuellen Elementes,
        // sondern->next' des vorigen Elementes gesetzt werden]
        (*p).next = (*h).next;
        // Hier wird p dann gelöscht (dann war die Änderung oben auch sinnlos, egal ob richtig oder falsch).
        free (p);         
      }
      // Und das war es dann auch; Du vergleichst nur das erste Element.
    }
    
    Bei der anderen Funktion musst Du die ganze Liste durchgehen, wenn Du alle Einträge mit->Land gleich XYZ' löschen willst. Das wäre mit den Nachnamen weniger sinnvoll (d.h. mehr Aufwand, aber nicht sinnvoller als oben).
     
Die Seite wird geladen...

Löschen eines Elements aus der Liste - Ähnliche Themen

Forum Datum
Löschen eines geklonten Laufwerks Windows XP Forum 19. Nov. 2015
Entfernt das Löschen eines Ordners auch alle darin enthaltenen Dateien? Windows 7 Forum 26. Mai 2015
Löschen eines Schüssels in der Registry will nicht gelingen Software: Empfehlungen, Gesuche & Problemlösungen 20. Okt. 2011
Seltsamer Hinweis beim Löschen eines Ordners Windows 7 Forum 21. Juli 2013
Löschen eines Ordners klappt nicht (Kaspersky Lab) Windows 7 Forum 23. Apr. 2011