Anzeige

in eine Linked list Delete funktion einfügen


BasicC

Erfahrenes Mitglied
#1
Hey Leute,

und zwar bin ich zur Zeit in den Letzten Zügen meines Codes .
Hauptsächlich geben wir eine Liste mit Büchern aus den Verlägen Autoren und ISBN nummern.
Paar sind sortiert etc.
So nun muss ich eine Selektion einbauen die es mir emöglich eine Autor zu löschen oder die ISBN zu löschen ..
Ich schreibe die Aufgabe mal rein. Und die jeweiligen Codes.
  1. Es soll durch eine Erweiterung des list-Interfaces die zusätzliche Möglichkeit geschaffen werden, dass der Benutzer einzelne Bücher/Autoren/Verlage aus den Listen löschen kann. (Beachten Sie, dass dies in einer array-basierenden Implementierung des list-Interfaces nur unter hohem Aufwand möglich wäre!)
    1. a) Erweitern Sie das list-Interface um eine FunktionList_delete löscht einen Knoten der Liste,
      Verwendung/Parameter ähnlich List_search() und implementieren Sie diese.
    2. b) Erweitern Sie das Menü des client-Programms um drei Einträge zum Löschen
      -4- Ein Buch (nach ISBN) loeschen
      -5- Einen Autor (nach Name) loeschen
      -6- Einen Verlag (nach Name) loeschen

      und implementieren Sie im client-Programm entsprechende Funktionen unter Verwen- dung von List_delete() (erweitern Sie dazu die Datenstruktur Verlag ebenfalls um einelist-Komponente seiner Bücher). Beachten Sie, dass zum vollständigen Löschen eines Buches auch die Anzahl der Bücher seines Autors/Verlags dekrementiert und das Buch aus der jeweiligen Bücherliste seines Autors/Verlags ausgetragen werden muss
meine List.h
C:
#ifndef __LIST_H__
#define __LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/****************************** Nummer a *******************************/
typedef struct lnode *link;
typedef struct list *List_t;
link lnode_new(void *data);
/*erstellt einen neuen Knoten*/
List_t List_new (const int maxlen);
/* initialisiert/allokiert eie neue Liste mit gegeb. Länge */
int List_add (List_t lst, void *data);
/* fügt ein(en) Datum(-pointer) an die Liste an */
int List_delete (List_t lst, void *data,
        int (*compar)(const void *, const void *));
/* sucht nach einem bestimmten Element in der Liste 
        und löscht dieses*/
int List_length (List_t lst);
/* gibt die aktuelle Länge der Liste zurück */
int List_size (List_t lst);
/* gibt die gesamt-Länge der Liste zurück */
void *List_search (List_t lst,const void *data,
        int (*compar)(const void *, const void *));
/* sucht nach einem bestimmten Element in der Liste */
void List_free (List_t lst);
/* gibt den Speicherplatz der Liste frei */
void List_sort (List_t lst, int (*compar)(const void *, const void*));
/*  sortiert die Liste nach dem in compar übergebenen Kriterien */
/****************************** Nummer b *******************************/
/*************************Iterator-Interface****************************/
typedef struct iterator *LIter_t;   /*Iterator-Struktur*/
LIter_t List_iterator(List_t lst);
/* erzeugt einen neuen Iterator für eine Liste */
int Iterator_hasNext (LIter_t it);
/* gibt an, ob noch ein weiteres Listenelement geliefert werden kann */
void * Iterator_next (LIter_t it);
/* liefert das nächste Listenelement */
void Iterator_free(LIter_t it);
/* gibt den Speicherplatz des Iterators frei */
#endif
meine list.c
C:
#include "list.h"
/****************************** Nummer a *******************************/
struct lnode{
    void *data;
    link next;
};
struct list{
    link head;                  /* void-pointer aus Daten   */
    link tail;                  /* konstante Listen größe   */
    unsigned int length;    /* aktuelle Tiefe der Liste */
};
link lnode_new(void *data){
    /*erstellt einen neuen Knoten*/
    link newnode;
    if ((newnode = malloc(sizeof(*newnode)))==NULL) return NULL;
    newnode->data=data;
    newnode->next=NULL;
    
    return newnode;
    
}
List_t List_new (const int maxlen){
    /* initialisiert/allokiert eie neue Liste mit gegeb. Länge */
    List_t lst;     /* Listen-Variable */
    /* für die angelegte Variable Speicher reservieren und auf NULL prüfen*/
    if ((lst  = (List_t)malloc(sizeof(struct list)))==NULL){
        return NULL;
    }   
    
    lst->head=NULL;
    lst->tail=NULL; 
    lst->length = 0;            /* aktuelle Länge der Liste auf 0 setzen */
    return lst;
}
int List_add (List_t lst, void *data){
    /* fügt ein(en) Datum(-pointer) an die Liste an */  
    if(lst==NULL) return 0;
    if(lst->head==NULL){
        if((lst->tail = lnode_new(data))==NULL) return 0;
        lst->head=lst->tail;        
    }else{
        if((lst->tail->next=lnode_new(data))==NULL) return 0;
        lst->tail=lst->tail->next;
    }
    return ++(lst->length);
}
int List_delete (List_t lst, void *data,
        int (*compar)(const void *, const void *)){
    /* sucht nach einem bestimmten Element in der Liste 
        und löscht dieses*/
    
    link rest = lst->head;
    
    /* solange noch ein rest-Element enthalten ist wird geprüft,
        ob dieses Element per compare-funktion mit dem zu 
        vergleichenden überein stimmt*/
    while (rest != NULL){
        if (compar(rest->data,data)==0) {
            link t = rest->next;
            rest->next = t->next;
            free(t);
            return --(lst->length);
        }
        rest=rest->next;
    }
    return 0;   
}
int List_length (List_t lst){
    /* gibt die aktuelle Länge der Liste zurück */
    return lst->length;
}
//int List_size (List_t lst){
    /* gibt die Gesamt-Länge der Liste zurück */
//  return lst->size;
//}
void *List_search (List_t lst,const void *data,
        int (*compar)(const void *, const void *)){
    /* sucht nach einem bestimmten Element in der Liste */
    
    link rest = lst->head;
    /* solange noch ein rest-Element enthalten ist wird geprüft,
        ob dieses Element per compare-funktion mit dem zu 
        vergleichenden überein stimmt, wenn ja, 
        gibt die aufgerufene Funktion 0 zurück und es wird 
        der Pointer auf das Element zurück gegeben */
    while (rest != NULL){
        if (compar(rest->data,data)==0) return rest->data;
        rest=rest->next;
    }
    return NULL ;
}
void List_free (List_t lst) {
    /* gibt den Speicherplatz der Liste frei */
    link nd = lst->head;
    
    /* solange nicht am Ende der Liste, 
        soll auf das aktuelle Element free gemacht werden */
    while (nd != NULL){
        link t = nd;
        nd = nd->next;
        free(t);
    }
    free(lst);  
}
void List_sort (List_t lst, int (*compar)(const void *, const void*)){
    /*  sortiert die Liste nach dem in compar übergebenen Kriterien */  
    //qsort(lst->lst_array,lst->length,sizeof(lst->lst_array[0]),compar);
}
/****************************** Nummer 2b ******************************/
/*************************Iterator-Interface****************************/
struct iterator {
    List_t list;
    unsigned int current;
};
LIter_t List_iterator(List_t lst){
    /* erzeugt einen neuen Iterator für eine Liste */
    LIter_t it;     /* Vairbale für den iterator */
    /* Speicher für iterator-Variable reservieren und auf NULL prüfen */
    if ((it =(LIter_t)malloc(sizeof(*it)))==NULL){
        return NULL;
    }
    it->list = lst;
    it->current = 0;
    return it;
}
int Iterator_hasNext (LIter_t it){
    /* gibt an, ob noch ein weiteres Listenelement geliefert werden kann */
    if (it==NULL) return 0; 
    return it->current < List_length(it->list);
}
void * Iterator_next (LIter_t it){
    /* liefert das nächste Listenelement */
    if (it==NULL)return NULL;
    if (!Iterator_hasNext(it)) return NULL;
    void *data = it->list->head->data;
    link nextnode = it->list->head->next;
    it->list->head = nextnode;  
    it->current++;
    return data;
}
void Iterator_free(LIter_t it){
    /* gibt den Speicherplatz des Iterators frei */
    link nd = it->list->head;
    while(nd != NULL){
        link t = nd;
        nd = nd -> next;
        free(t);
    }
    free(it);
}
meine Buecher.c
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "buecher_func.h"
#include "./list/list.h"
int show_menu(char *menu_entries[], const int num_entries) {
   /* gibt Menu auf stdout aus,
    * liefert Nummer des selektierten Men¸eintrags (0=Ende) */
   int i;
   char c;
   int sel;          /* Menueauswahl */
   int selOK = 0;    /* Flag, ob Selektion gueltig */
   /* Menue ausgeben (ggfs. wiederholt, bis Selektion im gueltigen Bereich) */
   while (! selOK) {
      printf("\n=== Menueauswahl ===\n");
      for (i = 0; i < num_entries; i++) {
         printf(" -%d- %s\n", i + 1, menu_entries[i]);
      }
      printf(" -0- Beenden\n");
      printf("Ihre Auswahl [0-%d]: ", num_entries);
      /* einen Integer lesen und pr¸fen */
      if (scanf("%d", &sel) == 1) {
         selOK = sel >= 0 && sel <= num_entries;
      }
      /* evtl. restl. (ung¸ltige) Eingabe auf der Zeile ¸berlesen */
      while ((c = getchar()) != EOF) {
         if (c == '\n') break;
      }
      if (! selOK) printf("*** Ungueltige Eingabe!\n");
   }
   printf("\n");
   /* gueltige Selektion zurueckgeben */
   return sel;
}
int main() {
        /* Texte der Men¸eintr‰ge (ohne '0=Beenden') */
   static char *menu_entries[] = {
      "Komplette Buecherliste ausgeben",
      "Top5-Autorenliste (mit Buechern) ausgeben",
      "Top5-Verlageliste ausgeben",
      "Ein Buch (nach ISBN) loeschen",
      "Einen Autor (nach Name) loeschen",
      "Einen Verlag (nach Name) loeschen",
   };
   const int num_entries = sizeof(menu_entries) / sizeof(menu_entries[0]);
   int sel;         /* Menu-Auswahl */

   enum {
      MAXBUCH           = 1000,         /* Maximalzahl Buecher */
      MAXAUTOR          = 300,  /* Maximalzahl Autoren */
      MAXVERLAG         = 60,   /* Maximalzahl Verlage */
      NUMTOP            = 5,    /* Groeße Bestenliste */
   };

   FILE *infile;              /* filepointer Eingabedatei */
   char infilename[] = "buecherliste.csv";
   List_t buecher, autoren, verlage;
   /*************************************************************
    * B¸cher-Datens‰tze einlesen und speichern
    *************************************************************/
   printf("\nBuecher-Liste\n");
   printf("=============\n\n");
   /* Eingabedatei oeffnen und pruefen */
   if ((infile = fopen(infilename, "r")) == NULL) {
      fprintf(stderr, " *** Fehler: Kann '%s' nicht zum Lesen oeffnen!\n",
              infilename);
      return 1;
   }
        /*      Listen fuer buecher, autoren und verlage erstellen 
                und pruefen, ob diese erstellt werden konnten   */
   if ((buecher=List_new(MAXBUCH))==NULL){
                fprintf(stderr,"Speicherzugriffsfehler! Nicht genuegend");
                fprintf(stderr," Speicherplatz fuer 'Buecher' vorhanden.");
   }
   if((autoren=List_new(MAXAUTOR))==NULL){
        fprintf(stderr,"Speicherzugriffsfehler! Nicht genuegend");
        fprintf(stderr," Speicherplatz fuer 'Autoren' vorhanden.");
   }
   if((verlage=List_new(MAXVERLAG))==NULL){
        fprintf(stderr,"Speicherzugriffsfehler! Nicht genuegend");
        fprintf(stderr," Speicherplatz fuer 'Verlage' vorhanden.");
   }
   /* alle Buecher-Datens‰tze einlesen */
   buecher_read(infile, buecher, autoren, verlage);
   /* Eingabedatei schliessen und Kontrollmeldung ausgeben*/
   fclose(infile);
   printf("Es wurden %d Buecher-Datensaetze\n", List_length(buecher));
   printf("aus %d unterschiedlichen Verlagen\n", List_length(verlage));
   printf("von %d unterschiedlichen Autoren eingelesen.\n\n", List_length(autoren));

   /*************************************************************
    * Ergebnis-Ausgabe/Menu
    *************************************************************/
        /* wiederholt Menue ausgeben bis '0=Beenden' gewaehlt */
   while ((sel = show_menu(menu_entries, num_entries))) {
      switch (sel) {
         case 1:
            printf(" --- Buecherliste\n");
                        buecher_print(buecher);
            break;

         case 2:
            printf("=== Top%d Autoren sortiert nach Anzahl Buecher ===\n", NUMTOP);
                                qsort_ausgabe_autoren(autoren, NUMTOP);
                        printf("\n");
            break;
         case 3:
            printf("=== Top%d Verlage sortiert nach Anzahl Buecher ===\n", NUMTOP);
                                qsort_ausgabe_verlage(verlage,NUMTOP);
                        printf("\n");
            break;
         case 4: /* Buch loeschen nach isbn */          
                break;
         case 5: /* Autor loeschen nach Name */
                break;
         case 6: /* Verlag loeschen nach Name */
                break;
      }
   }
   printf("Programm regulaer beendet.\n");
   return 0;

}
meine beucher_func.c
C:
#include "buecher_func.h"
/***********************************************************************/
enum {BUECHERMAX=50};
void buecher_read(FILE *infile,
                  List_t  buecher,List_t autoren,List_t verlage) {
   /* Liest das komplette Eingabe-file zeilenweise ein */
   enum { MAXLL = 240 };   /* max. input line length */
   char c, linebuf[MAXLL]; /* Einlesepuffer fuer eine Zeile */
   fgets(linebuf, sizeof(linebuf), infile); /* Kopfzeile ueberlesen */

   /* Schleife ueber alle Buecher-Datens‰tze, speichern */
   while (fgets(linebuf, sizeof(linebuf), infile)) {    
      /* Zeilenlaenge absichern */
      if (linebuf[strlen(linebuf)-1] != '\n') {
         fprintf(stderr,
                 " *** Hinweis: Zeile auf der Datei zu lang (>%d)! ", MAXLL);
         fprintf(stderr, "Diese Zeile ignoriert:\n *** >%s...<\n", linebuf);
         while ((c = fgetc(infile)) != EOF) {
            if (c == '\n') break; /* Rest der ueberlangen Zeile ueberlesen */
         }
         continue;   /* dieses (unvollstdg.) Buch ignorieren */
      }
      /* dieses Buch mit Verweisen auf Autor und Verlag speichern */
      buch_add(infile, linebuf, buecher, autoren, verlage);
   }
}
/***********************************************************************/
void buch_add(FILE *infile, char linebuf[],
              List_t buecher, List_t autoren, List_t verlage) {
   /* Erh‰lt die eingelesene Eingabezeile eines Buch-Datensatzes,
    * zerlegt diese am Trennzeichen in die Attribute und speichert diese.
    * In der Buch-Struktur werden Zeiger auf dessen Autor- und Verlag-
    * Element gespeichert.
    */
   const char *delim = ";\n";    /* CSV-Trennzeichen + NL! */
   char *verlagname, *autorname; /*Zwischenvariable fuer Verlag und Autor*/
   Buch *b= (Buch *)malloc(sizeof(Buch));
   /* Zeile zerlegen und Teile speichern */
   /* Titel;Autor;Verlag;Erscheinungsjahr;ISBN */
   b->titel            = strdup(strtok(linebuf, delim));
   autorname           = strtok(NULL, delim);
   verlagname          = strtok(NULL, delim);
   b->erscheinungsjahr = atoi  (strtok(NULL, delim));
   b->isbn             = strdup(strtok(NULL, delim));                                                                                                                                                                               /* Verlag im bisherigen Verlage-Feld suchen, ggfs. neu anlegen*/
   b->verlag = verlag_link(verlage, verlagname,b);

    /* Autor im bisherigen Autoren-Feld suchen, ggfs. neu anlegen */
   b->autor = autor_link(autoren, autorname,b); 

   if ((List_add(buecher, b))==0){
        return;
   }
}
/***********************************************************************/
void buecher_print(List_t  buecher) {
   /* Iteriert ¸ber B¸cherliste zur Ausgabe */
    unsigned int i=0;
    LIter_t list_iter;      /*Variable fuer den Iterator ueber die Liste*/
    /* Erzeugung eines Iterators ¸ber die Liste und zuweisung an die erzeugte
        Variable, pruefen ob NULL*/
   if ((list_iter = List_iterator(buecher))==NULL){
    printf("funktioniert nicht");
    return ;
   }
   /* Schleife ueber die Elemente einer Liste mit Hilfe des Iterators.
        Solange noch ein weiteres Element existiert, soll das
        Listenelement geholt und der buch_print Funktion als Buch-Struktur
        uebergeben. S*/
    while (Iterator_hasNext(list_iter)){    
        printf("%3d: ", ++i);
        buch_print((Buch *) Iterator_next(list_iter));
   }    
   printf("\n");
   Iterator_free(list_iter);
}
/***********************************************************************/
void buch_print(const Buch *b) {
   /* Gibt ausgew‰hlte Attribute eines Buches formatiert aus */
    
   printf("[%s] %s (%d): %s\n",b->isbn,
          (b->autor != NULL ? b->autor->name : "*unbekannt*"),
          b->erscheinungsjahr, b->titel);
}
/***********************************************************************/
/***********************************************************************/
/**********************AUTOREN-FUNKTIONEN*******************************/
/****************************ANFANG*************************************/
Autor *autor_link(List_t autoren, char *autorname, const Buch *buch){
    /* Sucht Autor, wenn nicht da, wird neuer Autor eingetragen */
        
    Autor *autor;       /* Pointer-Variable auf eine Verlag-Struktur anlegen */
    /* Speicher reservieren und auf NULL pruefen */
    if ((autor= (Autor *)malloc(sizeof(Autor)))==NULL) return NULL;
    /* uebergebenen Autornamen duplizieren und der Variable zuweisen */
    autor->name=strdup(autorname);
    Autor *exist_autor;
    /*  pruefen, ob verlag bereits in Liste existiert, wenn ja
        anzahl der Buecher des gefundenen Verlages erhoehen und
        nicht benoetigte verlag-variable freigeben  */
    if ((exist_autor=List_search(autoren,autor,comp_autor))!=NULL){
        exist_autor->anz_buecher++;
        free(autor);
        List_add(exist_autor->autors_buecher,buch);
        return exist_autor;
    }
    /*  bei neuem Autoren Anzahl der Buecher auf 1 setzen,
        die Buecherliste in der Autoren-Struktur erstellen,
        einen Pointer auf die Buchstruktur dem Autoren 
        und diesen der Autoren-Liste hinzufuegen */
    autor->anz_buecher=1;
    autor->autors_buecher=List_new(BUECHERMAX);
    List_add(autor->autors_buecher,buch);   
    List_add(autoren,autor);
    return autor;
}
/***********************************************************************/
int comp_autor (const void *p1, const void *p2){
    /* Vergleichsfunktion fuer den Namen eines Autoren */
   Autor *n1 = ((Autor*)p1);
   Autor *n2 = ((Autor*)p2);

   return strcmp(n1->name,n2->name); /* Name in der Struktur wird verglichen*/
 }
/***********************************************************************/
void qsort_ausgabe_autoren(List_t autoren, const int NUMTOPAUTOR){
    /* Funktion zur Ausgabe der gerodneten Autoren */       
    Autor *permu[List_length(autoren)]; 
    int i;
    
    /*permutationsvektor fuellen*/
    fill_autor_permu(permu, autoren);
    
    /*permu sortieren*/
    qsort(permu, List_length(autoren),
        sizeof(permu[0]), absteigendes_permu_autor);
    /*Ausgabe der geordneten Top 5*/
    for (i=0; i<NUMTOPAUTOR; i++){
        ausgabe_top5_autoren(permu, i); 
    }
}
/***********************************************************************/
void ausgabe_top5_autoren (Autor *permu[],const int el){
    int i=0;
    printf("%3d: (%3d) %s\n", el+1,(*permu[el]).anz_buecher, (*permu[el]).name);
    
    LIter_t list_iter;      /*Variable fuer den Iterator ueber die Liste*/
    /* Erzeugung eines Iterators ¸ber die Liste und zuweisung an die erzeugte
        Variable, pruefen ob NULL*/
    if ((list_iter = List_iterator((*permu[el]).autors_buecher))==NULL){
    printf("funktioniert nicht");
    return ;
    }
    /* Schleife ¸ber die Elemente einer Liste mit Hilfe des Iterators.
        Solange noch ein weiteres Element existiert, soll das
        Listenelement geholt und das Erscheinungsjahr und Titel des Buches
        ausgegeben werden. */
    while (Iterator_hasNext(list_iter)){    
        Buch *ab = (Buch *) Iterator_next(list_iter);
        printf("    %3d. (%d) %s \n", ++i,ab->erscheinungsjahr,ab->titel);
   }
   printf("\n");
   Iterator_free(list_iter);
}
/***********************************************************************/
void fill_autor_permu(Autor *permu[],  List_t autoren){
    /* fuellt einen Permutationsvektor fuer die Autoren 
        und sortiert die Buecher des jeweiligen Autoren
        in dessen Liste*/
    int i=0;
    LIter_t list_iter;  /*Variable fuer den Iterator ueber die Liste*/
    /* Erzeugung eines Iterators ¸ber die Liste und zuweisung an die erzeugte
        Variable, pruefen ob NULL*/
   if ((list_iter = List_iterator(autoren))==NULL){
    printf("funzt nicht");
    return ;
   }
   /* Schleife ¸ber die Elemente der Autorenliste mit Hilfe des Iterators.
        Solange noch ein weiteres Element in der Liste existiert, soll das
        Listenelement geholt und in dem aktuellen Array-Index des Permutations-
        vektors abgelegt werden. Danach wird der Index erhoeht.*/
    while (Iterator_hasNext(list_iter)){
        permu[i]=Iterator_next(list_iter);
        
        i++;
   }
   Iterator_free(list_iter);    
}
/***********************************************************************/
int absteigendes_permu_autor(const void *p1, const void *p2){
    /* Sortierreihenfolge des permus f¸r qsort */
   int n1 = (**(Autor**)p1).anz_buecher;
   int n2 = (**(Autor**)p2).anz_buecher;

   if (n1==n2)return 0;
   if (n1<n2)return 1;
   return -1;
}
/***********************************************************************/
int autor_buch_sort(const void *p1, const void *p2){
    /* Sortierreihenfolge der Buecher eines Autors f¸r qsort */
    
   int n1 = (**(Buch**)p1).erscheinungsjahr;
   int n2 = (**(Buch**)p2).erscheinungsjahr;

   if (n1==n2)return 0;
   if (n1>n2)return 1;
   return -1;
}
/*****************************ENDE**************************************/
/***********************************************************************/
/***********************************************************************/
/**********************VERLAGE-FUNKTIONEN*******************************/
/****************************ANFANG*************************************/
Verlag *verlag_link(List_t verlage, char *verlagname, const Buch *buch){
    /* Sucht Verlag, wenn nicht da, wird neuer Verlag eingetragen */
    
    Verlag *verlag; /* Pointer-Variable auf eine Verlag-Struktur anlegen */
    /* Speicher reservieren und auf NULL pr¸fen */
    if ((verlag= (Verlag *)malloc(sizeof(Verlag)))==NULL) return NULL;
    /* ¸bergebenen Verlagnamen duplizieren und der Variable zuweisen */
    verlag->name=strdup(verlagname);    
    Verlag *exist_verlag;   
    /*  pr¸fen, ob verlag bereits in Liste existiert, wenn ja
        anzahl der Buecher des gefundenen Verlages erhˆhen und
        nicht benˆtigte verlag-variable freigeben   */
    if ((exist_verlag=List_search(verlage,verlag,comp_verlag))!=NULL){      
        exist_verlag->anz_buecher++;
        free(verlag);
        List_add(exist_verlag->verlags_buecher,buch);
        return exist_verlag;
    }
   /*   bei neuem Verlag anzahl der Buecher auf 1 setzen
        die Buecherliste in der Verlage-Struktur erstellen,
        einen Pointer auf die Buchstruktur dem Verlag
        und diesen der Verlag-Liste hinzuf¸gen */
    verlag->anz_buecher=1;
    verlag->verlags_buecher=List_new(BUECHERMAX);
    List_add(verlag->verlags_buecher,buch); 
    List_add(verlage,verlag);
    return verlag;  
}
/***********************************************************************/
int comp_verlag (const void *p1, const void *p2){
    /* verlgeichsfunktion fuer die Verlage */
    
   Verlag *n1 = ((Verlag*)p1);
   Verlag *n2 = ((Verlag*)p2);

   return strcmp(n1->name,n2->name); /* Name in der Struktur wird verglichen
                                                 Rueckgabe 0, wenn gleich */
 }
/***********************************************************************/
void qsort_ausgabe_verlage(List_t verlage, const int NUMTOP){
    /* Funktion zur Ausgabe der gerodneten Verlage */   
    Verlag *permu[List_length(verlage)];    
    int i;
    
    /* permutationsvektor fuellen */
    fill_verlag_permu(permu, verlage);
    
    /* permu sortieren */
    qsort(permu, List_length(verlage),
                    sizeof(permu[0]), absteigendes_permu_verlag);
    
    /* Ausgabe der geordneten Top 20 */
    for (i=0; i<NUMTOP; i++){
        ausgabe_top5_verlage(permu, i); 
    }
}
/***********************************************************************/
void ausgabe_top5_verlage (Autor *permu[],const int el){
    int i=0;
    printf("%3d: (%3d) %s\n", el+1,(*permu[el]).anz_buecher, (*permu[el]).name);
    
    LIter_t list_iter;      /*Variable fuer den Iterator ¸ber die Liste*/
    /* Erzeugung eines Iterators ¸ber die Liste und zuweisung an die erzeugte
        Variable, pruefen ob NULL*/
    if ((list_iter = List_iterator((*permu[el]).autors_buecher))==NULL){
    printf("funzt nicht");
    return ;
    }
    /* Schleife ueber die Elemente einer Liste mit Hilfe des Iterators.
        Solange noch ein weiteres Element existiert, soll das
        Listenelement geholt und das Erscheinungsjahr und Titel des Buches
        ausgegeben werden. */
    while (Iterator_hasNext(list_iter)){    
        Buch *ab = (Buch *) Iterator_next(list_iter);
        printf("    %3d. (%d) %s \n", ++i,ab->erscheinungsjahr,ab->titel);
   }
   printf("\n");
   Iterator_free(list_iter);
}
/***********************************************************************/
void fill_verlag_permu(Verlag *permu[],  List_t verlage){
    /* f¸llt einen Permutationsvektor fuer die Verlage 
        und sortiert die Buecher des jeweiligen Verlags
        in dessen Liste*/
    int i=0;
    LIter_t list_iter;  /*Variable fuer den Iterator ueber die Liste*/
    /* Erzeugung eines Iterators ¸ber die Liste und zuweisung an die erzeugte
        Variable, pr¸fen ob NULL*/
   if ((list_iter = List_iterator(verlage))==NULL){
    printf("funzt nicht");
    return ;
   }
   /* Schleife ¸ber die Elemente der Autorenliste mit Hilfe des Iterators.
        Solange noch ein weiteres Element in der Liste existiert, soll das
        Listenelement geholt und in dem aktuellen Array-Index des Permutations-
        vektors abgelegt werden. Danach wird der Index erhˆht.*/
    while (Iterator_hasNext(list_iter)){        
        permu[i]=(Verlag *) Iterator_next(list_iter);
        i++;
   }
   Iterator_free(list_iter);    
}
/***********************************************************************/
int absteigendes_permu_verlag(const void *p1, const void *p2){
    /* Sortierreihenfolge des permus fuer qsort */
    int n1 = (**(Verlag**)p1).anz_buecher;
   int n2 = (**(Verlag**)p2).anz_buecher;

   if (n1==n2)return 0;
   if (n1<n2)return 1;
   return -1;
}
/*****************************ENDE**************************************/
/***********************************************************************/
meine buecher_func.h
C:
#ifndef BUECHER_FUNC_H
#define BUECHER_FUNC_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./list/list.h"
/* Struktur einer Autor-Definition */
typedef struct {
   char *name;                   /* vollstdg. Name dieses Autors */
   unsigned short anz_buecher;   /* Anzahl der B¸cher dieses Autors */
   List_t autors_buecher;           /* Liste mit Pointern auf Buecher des Autoren*/
} Autor;
/* Struktur einer Verlag-Definition */
typedef struct {
   char *name;                   /* vollstdg. Name dieses Verlags */
   unsigned short anz_buecher;   /* Anzahl der B¸cher dieses Verlags */
   List_t verlags_buecher;          /* Liste mit Pointern auf Buecher des Verlags*/
} Verlag;
/* Struktur einer Buch-Definition */
typedef struct {
   char *titel;                     /* Zeiger auf Titelstring */
   Autor *autor;                    /* Zeiger auf Element des Autoren-arrays */
   Verlag *verlag;                  /* Zeiger auf Element des Verlage-arrays */
   unsigned short erscheinungsjahr; /* Jahreszahl 4-stellig, z. B.: 2009 */
   char *isbn;                      /* Zeiger auf ISBN-string */
} Buch;

void buecher_read(FILE *infile,
                  List_t  buecher,
                  List_t  autoren,
                  List_t  verlage);
/* Liest das komplette Eingabe-file zeilenweise ein */

void buch_add(FILE *infile, char linebuf[],
              List_t  buecher,
              List_t  autoren,
              List_t  verlage);
/* Erh‰lt die eingelesene Eingabezeile eines Buch-Datensatzes,
 * zerlegt diese am Trennzeichen in die Attribute und speichert diese.
 * In der Buch-Struktur werden Zeiger auf dessen Autor- und Verlag-
 * Element gespeichert.
 */

void buecher_print(List_t  buecher);
/* Iteriert ¸ber B¸cherliste zur Ausgabe */
void buch_print(const Buch *b);
/* Gibt ausgew‰hlte Attribute eines Buches formatiert aus */
/***********************AUTOREN-PROTOTYPEN*************************/
Autor *autor_link(List_t  autoren, char *autorname, const Buch *buch);
/* Sucht einen Autoren, wenn dieser nicht existiert, wird ein neuer Autor 
    in der vorhandenen Liste eingetragen */
int comp_autor (const void *p1, const void *p2);
/* Vergleichsfunktion f¸r den Namen von zwei Autoren */
void qsort_ausgabe_autor(List_t  autoren, const int NUMTOP);
/* Funktion zur Ausgabe der gerodneten Autoren */
void ausgabe_top5_autoren (Autor *permu[],const int el);
void fill_autor_permu(Autor *permu[],  List_t  autoren);
/* f¸llt einen Permutationsvektor f¸r die Autoren und sortiert 
    die Buecher des jeweiligen Autoren in dessen Liste */
int absteigendes_permu_autor(const void *p1, const void *p2);
/* Sortierreihenfolge des permus f¸r qsort */
int autor_buch_sort(const void *p1, const void *p2);
/* Sortierreihenfolge der Buecher eines Autors f¸r qsort */
    
/***********************VERLAGE-PROTOTYPEN**************************/
Verlag *verlag_link(List_t verlage, char *verlagname, const Buch *buch);
/* Sucht einen Verlag, wenn dieser nicht existiert, wird ein neuer Verlag 
    in der vorhandenen Liste eingetragen */
    
void qsort_ausgabe_verlage (List_t  verlage, const int NUMTOP);
/* Funktion zur Ausgabe der gerodneten Verlage */
void ausgabe_top5_verlage (Autor *permu[],const int el);
void fill_verlag_permu(Verlag *permu[], List_t  verlage);
/* f¸llt einen Permutationsvektor f¸r die Verlage */
int absteigendes_permu_verlag(const void *p1, const void *p2);
/* soriterreihenfolge des permu f¸r qsort */
int comp_verlag (const void *p1, const void *p2);
/* Vergleichsfunktion f¸r den Namen von zwei Verlage */
#endif
 

cwriter

Erfahrenes Mitglied
#2
und zwar bin ich zur Zeit in den Letzten Zügen meines Codes .
Hauptsächlich geben wir eine Liste mit Büchern aus den Verlägen Autoren und ISBN nummern.
Paar sind sortiert etc.
So nun muss ich eine Selektion einbauen die es mir emöglich eine Autor zu löschen oder die ISBN zu löschen ..
Hi

Und die Frage ist...?

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
#3
Wie krieg ich es hin, dass ich diese Lösch Funktion einbaue ?
ich habe sie deklariert in list.c aber mehr kann ich damit nicht anfangen ?
 

cwriter

Erfahrenes Mitglied
#4
ich habe sie deklariert in list.c aber mehr kann ich damit nicht anfangen ?
Du hast sie sogar definiert. Ist die Frage, wie du sie benutzt?

Du weisst ja wohl, was du löschen willst. Dann kannst du per
C:
int comp(const void* a, const void* b)
{
    //Condition hier einfügen, z.B.
    return a == b;
    // Du kannst auch casten, wenn du weisst, was du tust.
}
List_delete(list, data, &comp);
Einträge löschen.

Entsprechend bei dir:
list ist die Buchliste
Du kannst a auf Buch casten und die isbn- und Autor-Felder überprüfen. Eigentlich ist das nicht wirklich schwer; die Funktionsdefinitionen sind wohl schwieriger... Selbst geschrieben?

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
#5
Zum Teil selbst geschrieben aber mit der Erklärung komm ich nicht weiter ich hatte vorher noch nie diese Delete funktion hab echt kein schimmer :/
 

cwriter

Erfahrenes Mitglied
#6
ich hatte vorher noch nie diese Delete funktion hab echt kein schimmer :/
Diese Deletefunktion hat 3 Parameter:
1. Die Liste, aus der etwas gelöscht werden soll.
2. Einen Wert, der immer an die Funktion im 3. Parameter übergeben wird.
3. Eine (Prädikats-)Funktion, die 0 zurückgibt, wenn das Prädikat P(a,b) zutrifft. Eine einfache Prädikatsfunktion ist also "a ≠ b", denn: a ≠ b ist 0, wenm a == b, sonst 1.
(insbesondere war das "a == b" verkehrt, so würden alle Werte gelöscht, auf die das Prädikat NICHT zutrifft).

Deine Aufgabe ist, ein geeignetes Prädikat zu finden, sodass du einen Pointer auf einen Autor und/oder einen Pointer auf eine ISBN übergeben kannst, wobei dann ein bestimmtes Buch gelöscht werden soll.

Dies ist aber deine Aufgabe, da du schon sehr viel durch Template/Gruppe/Andere Foren zu bekommen haben scheinst, wäre es kontraproduktiv, wenn ich dir das vorkaue.

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
#7
Ich habe keine Foren angeschrieben ?
Das ist mein erster Thread.

Also verstehen tu ich es etwas aber umsetzen auf mein Code geht nicht . Kriege ich nicht hin. :/
 

cwriter

Erfahrenes Mitglied
#8
Hm.

Ein Beispiel:
C:
/* Struktur einer Katze-Definition */
typedef struct {
   char *name;
   int zuletzt_gefüttert;
} Katze;

// Wir haben eine Liste aus Katzen (vielleicht die Haustiere der Nachbarin).
// Nun ist eine Katze entlaufen und ist viel glücklicher mit ihrer grossen Katerliebe im Wald.
// Die Nachbarin will die Katze demnach aus der Liste löschen, und zwar nach dem Namen.

// Die Liste mit allen Katzen heisst "katzen".

// Wir kennen den Namen der Katze
char catname[] = {"Lily"};
List_delete(katzen, (const void*)catname, &catnamecomp);

// Wobei "catnamecomp" definiert ist als

int catnamecomp(const void* a, const void* b)
{
    // b ist immer ein pointer auf "catname", also "Lily". Eigentlich könnte man die Funktion unär machen, aber das ist ein anderes Thema. (Genau genommen gibt es generell nur unäre Funktionen)
    return strcmp(((Katze*)a)->name, (const char*)b);
}
So. Das kannst du jetzt adaptieren.

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
#9
Und jetzt muss ich dir dazu noch sagen das die Buecherliste 948 Einträge hat darunter Autor Verlag Erscheinungsjahr und ISBN
 

cwriter

Erfahrenes Mitglied
#10
Und jetzt muss ich dir dazu noch sagen das die Buecherliste 948 Einträge hat darunter Autor Verlag Erscheinungsjahr und ISBN
?

Sorry, wenn ihr Listen habt, dann habt ihr Structs schon gehabt. Das ist nun echt kein Hexenwerk mehr.
Ich helfe dir gerne, wenn du spezifische Probleme mit existierendem Code hast oder einfach Grundlagen erklärt haben möchtest, aber komplette Aufgaben löse ich dir nicht.
Du kannst natürlich darauf hoffen, dass andere im Forum das tun, aber die Chancen dazu stehen eher schlecht. "Hilfe zur Selbsthilfe" ist das Motto der Stunde.

Die Anzahl Einträge sind höchstens relevant, wenn du dir um Performance Gedanken machst, aber O(n) bei <= 10e6 ist i.d.R. vernachlässigbar. Optimieren könntest du das höchstens auf entsprechend sortierten Listen (per binary search), aber selbst dann hast du halt O(log(n)) Comparisons und O(n) iterationen (ist ja dennoch eine Liste...), also so viel wirst du nicht gewinnen, eher verlieren (Listen sind nicht Random Access Structures).

Versuch's erstmal selbst, dann können wir uns dein Ergebnis anschauen.

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
#11
C:
case 4: /* Buch löschen nach isbn */
                printf("ISBN NUmmer eingeben: ");
                fgets(isbn, 100, stdin);
                strip (isbn);
                printf("ISBN: '%s'\n", isbn);
                Buch* buch= findBuchbyISBN(buecher,isbn);
                void* data= (void*) buch;
                List_delete(buecher,data,comp_byAdress);                
                break;
so ungefähr habe ich es hinbekommen nun ist das Problem vorhanden, dass das Programm meine eingegebene ISBN nicht löscht
 
Anzeige

Neue Beiträge

Anzeige