if-struct-pointer
-
mein Post war vielleicht einbisschen missverständlich, tschuldigung
die Pointer wurden schon alle gerichtet
also
jeder struct speicher hat auch einen dazugehörigen pointerdas wollte ich alles mit dem "...." überspringen, da es hauptsächlich klappt.
wie gesagt nur bei dieser if-Bedingung klappt das nicht
Bei dem kleinen Probezeilen habe ich es einbisschen vermasselt
sollte
if(haus_pointer->pointer->zahl)
heißen, was auch bei den übrigen Probezeilen übernehmen kann
-
Zeig' vollständigen Code!
-
Bitte
die Werte habe ich Probeweise immer mit strcpy() eingefügtstruct kunde { int kdn_Nr; char vorName[21]; char nachName[21]; }; struct buch { int buch_Nr; char buch_Titel[21]; char buch_Autor[21]; struct kunde *ausleih_cmt; }; main() { int x; int int_auswahl=1; int check_kunde; struct kunde struct_kunde[500]={NULL}; struct kunde *ptr_kunde[500]={NULL}; struct buch struct_buch[1000]={NULL}; struct buch *ptr_buch[1001]={NULL}; for(x=0;x<=999;x++) { if(x<=499) ptr_kunde[x]=&struct_kunde[x]; ptr_buch[x]=&struct_buch[x]; } ptr_buch[0]->ausleih_cmt=ptr_kunde[0]; Ausleihliste(ptr_buch); } void Ausleihliste(struct buch *ptr_buch[]) { int x; printf("---------------------------\n"); for(x=0;x<=999;x++) { if(ptr_buch[x]->buch_Nr=='\0') break; else if(ptr_buch[x]->ausleih_cmt->kdn_Nr!='\0') { printf("%-10d%-10s%-10s%-10d%-10s%-10s\n", ptr_buch[x]->buch_Nr, ptr_buch[x]->buch_Autor, ptr_buch[x]->buch_Titel, ptr_buch[x]->ausleih_cmt->kdn_Nr, ptr_buch[x]->ausleih_cmt->nachName, ptr_buch[x]->ausleih_cmt->vorName); } } printf("---------------------------\n\n"); }
-
#include <stdio.h> #include <string.h>
denk' ich mir jetzt mal dazu.
Es heißt
int main( void )
. Sagt dir das dein Compiler nicht?
Abx = 1
inAusleihliste
dereferenzierst du Nullpointer.
Ausgegeben wird nichts, dakunde::cdn_Nr
nie etwas anderes als0
ist.
Warum Vergleichst du einen Integer mit '\0'?
Wofür die ganzen Pointer?
...
-
ja eine 0 sollte auch reichen, habe einbisschen an der if(pointer=='\0') gearbeitet und es einfach übernommen.
so viele Pointer, weil es die Aufgabe so verlangt hatte. mehr kann ich dazu auch nicht sagen.
also wenn x=1 ist, sollte er das ja überspringen, was er nicht macht, das Programm hängt sich auf und dann bin ich wieder raus
-
Swordfish schrieb:
Es heißt
int main( void )
. Sagt dir das dein Compiler nicht?Wieso?
main()
ist absolut kompatibel mitint main(void)
. Denk dran: C(89), nicht C++.
-
goddammit
-
spagetti schrieb:
so viele Pointer, weil es die Aufgabe so verlangt hatte. mehr kann ich dazu auch nicht sagen.
... und die Aufgabenstellung darfst/willst du nicht verraten?
spagetti schrieb:
also wenn x=1 ist, sollte er das ja überspringen, was er nicht macht, [...]
Woher weißt du das? Bist du mit einem Debugger durchgestept?
spagetti schrieb:
[...] das Programm hängt sich auf und dann bin ich wieder raus
Klar hängt sich das Ding auf, wenn du Nullpointer dereferenzierst...
-
nein, so war das nicht gemeint.
Aufgabenstellung:
"[...]Legen Sie ein
Array von Pointern an, die auf den Datentyp kunde zeigen können[...]"ja ich hab einen Breakpoint kurz davor gesetzt und bin ihn step-für-step bis dahin gefolgt.
die if() soll ja dafür sorgen dass er die Ausgabe überspringt falls es ein NULL-pointer ist. Habe schon paar Sachen versucht als Bedingung, entweder springt er nie rein, oder er läuft mit dem NULL-pointer rein
ich kann auch nicht sagen was ich bis jetzt schon versucht habe, da ich schon mindestens 2 Tage nur an dieser if() sitze
-
Ok. Hab' das break überlesen.
Was stimmt jetzt an http://ideone.com/7wsgih nicht?
-
if(ptr_buch[x]->ausleih_cmt->kdn_Nr!='\0')
ist nie falsch, also wird die ausgabe nicht übersprungen, wenn es sich um einen NULL-pointer handelt.
bei mir zumindest nicht
-
spagetti schrieb:
if(ptr_buch[x]->ausleih_cmt->kdn_Nr!='\0')
ist nie falsch, also wird die ausgabe nicht übersprungen, wenn es sich um einen NULL-pointer handelt.
kdn_Nr
ist kein Pointer!? Wo sollkdn_Nr
etwas anderes als0
sein/werden?Warum nicht mal
ptr_kunde[0]->kdn_Nr = 42; strcpy( ptr_kunde[0]->vorName, "foo" ); strcpy( ptr_kunde[0]->nachName, "bar" ); ptr_buch[0]->buch_Nr = 3; strcpy( ptr_buch[0]->buch_Titel, "baz" ); strcpy( ptr_buch[0]->buch_Autor, "bat" ); ptr_buch[0]->ausleih_cmt=ptr_kunde[0]; Ausleihliste( ptr_buch );
?
-
ich meinte das ganze
ptr_buch->ausleih_cmt ist ja ein pointer.
kdn_Nr habe ich erst im letzten Test gemacht
kdn_Nr/ausleih_cmt soll 0 sein wenn dem buch noch kein ausleih_cmt zugewiesen wurde
also nur
arr_buch->buch_Nr
arr_buch->autor
arr_buch->titel
sind vergebenarr_buch->ausleih_cmt
ist noch leer, wodurch eine Fehlermeldung kommen sollte, oder die funktion beendet werden soll,
wenn die vorhanden ist, soll das alles ausgegeben werdenWenn alle daten da sind, wird auch bei mir alles ohne probleme ausgegeben
-
ptr_kunde[0]->kdn_Nr = 42; strcpy( ptr_kunde[0]->vorName, "foo" ); strcpy( ptr_kunde[0]->nachName, "bar" ); ptr_buch[0]->buch_Nr = 3; strcpy( ptr_buch[0]->buch_Titel, "baz" ); strcpy( ptr_buch[0]->buch_Autor, "bat" ); ptr_buch[0]->ausleih_cmt=ptr_kunde[0]; ptr_buch[1]->buch_Nr = 4; strcpy( ptr_buch[1]->buch_Titel, "bazahah" ); strcpy( ptr_buch[1]->buch_Autor, "batahah" ); // ptr_buch[1]->ausleih_cmt = 0; <- is's eh schon ... Ausleihliste(ptr_buch); /* snip */ void Ausleihliste(struct buch *ptr_buch[]) { int x; printf("---------------------------\n"); for(x=0;x<=999;x++) { if( ptr_buch[x] == 0 || ptr_buch[x]->buch_Nr == 0 ) { // <- das Buch gibts ned. break; } else { printf( "\t%d\t%s\t%s", ptr_buch[x]->buch_Nr, ptr_buch[x]->buch_Autor, ptr_buch[x]->buch_Titel ); if( ptr_buch[x]->ausleih_cmt != 0 && ptr_buch[x]->ausleih_cmt->kdn_Nr != 0 ) { printf( "\t%d\t%s\t%s", ptr_buch[x]->ausleih_cmt->kdn_Nr, ptr_buch[x]->ausleih_cmt->nachName, ptr_buch[x]->ausleih_cmt->vorName ); } putchar( '\n' ); } } printf("---------------------------\n\n"); }
... aber irgendwie hab' ich den Verdacht, daß das nicht im Sinne des Aufgabenstellers ist. Magst mal die /ganze/ Aufgabe zeigen?
-
"[...]bauen Sie schließlich die Anweisungen für den Menüpunkt zum Auflisten der verliehenen Bücher ein. Dazu
durchsuchen Sie den Katalog und schauen nach den Ausleihvermerken. Ist ein Kunde als Ausleiher
vermerkt, so geben Sie das Buch und den Kunden aus. Außerdem zählen Sie die Anzahl der gefundenen
Einträge und geben das Ergebnis zum Schluss aus.[...]"Katalog ist mein ptr_buch
ausleihvermerk ist mein ptr_buch->ausleih_cmt
kunde ist ein struct kunde *Der Aufgabenzettel ist 4 Seiten lang, doch nur das bezieht sich auf diesen Teil
-
spagetti schrieb:
"[...]Der Aufgabenzettel ist 4 Seiten lang, [...]
... und in den ganzen vier Seiten steht nichts von "dynamisch"? Copy&Paste ist nicht?
-
Aufgabe 2.1
Jeder Kunde wird in unserem System mit folgenden Angaben geführt:
- Kunden-Nummer
- Vorname
- Nachname
Jedes Buch wird in unserem System mit folgenden Angaben geführt:
- Buch-Nummer
- Titel
- Autor
- Ausleihvermerk (welcher Kunde hat das Buch zurzeit ausgeliehen?)
Das Programm soll eine einfache Menüsteuerung erhalten, die es dem Benutzer erlaubt, neue Kunden und
Bücher einzugeben. Außerdem soll er eine Liste der Kunden oder Bücher anfordern können. Dabei soll das
Programm erst dann beendet werden, wenn der Benutzer dies wünscht. Das könnte etwa so aussehen:Gehen Sie bei der Programmentwicklung folgendermaßen vor:
- deklarieren Sie einen struct-Datentyp, der z. B. kunde heißt, mit den 3 Komponenten: Kundennummer als
Ganzzahl, Vorname als String, Nachname als String. Jeder Datensatz eines Kunden, der später angelegt
wird, soll von diesem Datentyp sein.
- deklarieren Sie als Vorlage für einen Buch-Datensatz einen weiteren struct-Datentyp, der z. B. buch heißt,
mit den 4 Komponenten: Inventarnummer als Ganzzahl, Titel und Autor jeweils als String und den
Ausleihvermerk als Pointer vom Typ kunde.
- zur Verwaltung der Kunden-Daten dient ein Array, das Pointer auf die Datensätze enthält. Legen Sie ein
Array von Pointern an, die auf den Datentyp kunde zeigen können. Dieses Array wird unsere Kundenkartei.
Mit dessen Hilfe haben wir Zugriff auf alle Daten unserer Kunden. Initialisieren Sie das Array mit NULLPointern,
da die Kundenkartei ja noch keine Einträge enthält. Die Größe des Arrays bestimmt die maximale
Anzahl von Kunden.
- legen Sie analog dazu ein Array von Pointern an, die auf den Datentyp buch zeigen können. Initialisieren
Sie auch dieses Array mit NULL-Pointern. Die Größe des Arrays bestimmt die maximale Anzahl von
Büchern. Dieses Array ist der "Katalog".
- schreiben Sie eine Funktion für die Kundeneingabe. Diese Funktion soll eine Datenstruktur vom Typ kunde
dynamisch erzeugen (mit malloc), die Daten vom Benutzer anfordern und als Rückgabewert den Pointer
auf die neue Datenstruktur liefern. Der Rückgabewert wird im Array der Kundenkartei gespeichert.
- mit jedem Aufruf der Funktion wird ein neuer Kunde angelegt und eine neue Position des Kundenkartei-
Array beschrieben, so dass sich die Kartei sukzessive aufbaut.
- schreiben Sie eine ähnliche Funktion zum Erfassen eines neuen Buches. Buch-Nummer, Autor und Titel
werden vom Benutzer eingegeben. Der Ausleihvermerk soll zu NULL initialisiert werden, da das neue Buch
ja noch nicht verliehen ist.
- mit jedem Aufruf dieser Funktion wird ein neues Buch in die Bibliothek aufgenommen und eine neue
Position des Katalog-Array beschrieben, so dass sich der Katalog sukzessive aufbaut.
- schreiben Sie eine Funktion, die die Kundenkartei ausgibt. Diese Funktion soll per "call by reference" das
Kundenkartei-Array als Parameter bekommen.
- schreiben Sie eine ähnliche Funktion, die den Bücherkatalog ausgibt. Diese Funktion soll per "call by
reference" das Katalog-Array als Parameter bekommen.
- erzeugen Sie eine einfache Menüsteuerung, die es erlaubt die Eingabe und Ausgabe beliebig oft
auszuführen.Aufgabe 2.2
Das zweite Modul erweitert das System unserer Bibliothek um die Verleihabwicklung:
- Eingabe: welches Buch, welcher Kunde?
- Auflistung aller verliehenen Bücher
Dazu erweitern wir das Menü um 2 Optionen. Beim Verleihvorgang wird der Kunde mit Hilfe der Kunden-
Nummer angegeben und das Buch mit der Buch-Nummer. Dabei soll das Programm erkennen, wenn der
Benutzer eine nicht existierende Nummer eingibt.Der Quellcode der ersten Aufgabe kann vollständig wiederverwendet werden.
Gehen Sie bei der Programmentwicklung folgendermaßen vor:
- erweitern Sie das Menü für die Eingabe eines Verleihvorgangs und die Auflistung der verliehenen Bücher
- schreiben Sie eine Funktion zum Suchen in der Kundenkartei. Diese Funktion bekommt die Kunden-
Nummer und das Kundenkartei-Array als Parameter übergeben. Damit sucht sie in dem Array nach dem
passenden Eintrag, indem sie mit Hilfe der Pointer indirekt auf die Datensätze der Kunden zugreift und die
Kunden-Nummer vergleicht. Wenn der Datensatz mit der richtigen Nummer gefunden wurde, gibt die
Funktion als Rückgabewert den Pointer dieses Datensatzes zurück. War die Suche erfolglos, soll ein NULLPointer
zurückgegeben werden.
- schreiben Sie analog dazu eine Funktion zum Suchen in dem Bücherkatalog. Diese Funktion bekommt die
Buch-Nummer und das Buchkatalog-Array als Parameter übergeben. Ansonsten arbeitet diese Funktion
wie die oben.
- bauen sie nun die Anweisungen für den Menüpunkt zum Ausleihen eines Buches ein:
- dazu fordern Sie den Benutzer zur Eingabe der Kundennummer auf. Mit dieser Eingabe rufen Sie die
Suchfunktion auf. Wird der Kunde gefunden, so bestätigt das Programm dies durch die Ausgabe des
Namens. War die Suche erfolglos, wird der Fehler gemeldet und der Vorgang abgebrochen.
- verfahren Sie genauso für die Eingabe des gewünschten Buches.
- waren beide Eingaben erfolgreich, so kommt die bisher noch nicht benutzte Struktur-Komponente
"Ausleihvermerk" des Buches ins Spiel. Sie soll anzeigen, wer (=Pointer auf den Kunden) das Buch
ausgeliehen hat. Ist das Buch noch nicht ausgeliehen, so ist der Ausleihvermerk ein NULL-Pointer und
Sie ersetzen diesen durch den Pointer auf den Kunden. Damit ist markiert, dass das Buch jetzt
verliehen ist (Pointer ungleich NULL) und an wen (Pointer zeigt auf den Kunden). War der Vermerk
jedoch schon gesetzt, so geben Sie eine Meldung aus, dass das Buch schon vergeben ist und sie
brechen den Vorgang ab.
- bauen Sie schließlich die Anweisungen für den Menüpunkt zum Auflisten der verliehenen Bücher ein. Dazu
durchsuchen Sie den Katalog und schauen nach den Ausleihvermerken. Ist ein Kunde als Ausleiher
vermerkt, so geben Sie das Buch und den Kunden aus. Außerdem zählen Sie die Anzahl der gefundenen
Einträge und geben das Ergebnis zum Schluss aus.
-
Ich habe einen alternativ-Lösung
und zwar lass ich den ptr_buch->ausleih_cmt auf {0,"0","0"}
vordefiniert
also nicht wirklich ein NULL-pointermit malloc hätte der pointer unsinnige Werte mit denen ich nichts anfangen konnte,
das "dynamisch" hat mich auf die Idee gebracht,
echt vielen Dank für die Hilfe
-
Dein Asatz ist schon Käse.
Geschmacksmuster:
#include <memory.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define MAX_CUSTOMERS 1024 #define MAX_BOOKS 512 #define MAX_BUFFER 128 void clear_stdin() { int ch = 0; while( ( ch = getchar() ) != '\n' && ch != EOF ) ; } /* - deklarieren Sie einen struct-Datentyp, der z. B. kunde heißt, mit den 3 Komponenten: Kundennummer als Ganzzahl, Vorname als String, Nachname als String. Jeder Datensatz eines Kunden, der später angelegt wird, soll von diesem Datentyp sein. */ typedef struct customer_tag { unsigned id; char* name; char* surname; } customer_t; /* - schreiben Sie eine Funktion für die Kundeneingabe. Diese Funktion soll eine Datenstruktur vom Typ kunde dynamisch erzeugen (mit malloc), die Daten vom Benutzer anfordern und als Rückgabewert den Pointer auf die neue Datenstruktur liefern. Der Rückgabewert wird im Array der Kundenkartei gespeichert. */ customer_t* create_customer( unsigned id ) { char buffer[ MAX_BUFFER ]; size_t input_length = 0; customer_t *result = NULL; if( ++id > MAX_CUSTOMERS ) { return NULL; } result = malloc( sizeof( *result ) ); if( result == NULL ) { fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr ); return NULL; } result->id = id; clear_stdin(); while( printf( "Name: " ), !fgets( buffer, sizeof( buffer ), stdin ) ) { fputs( "Eingabefehler, bitte wiederholen!\n", stderr ); clear_stdin(); } input_length = strlen( buffer ); if( input_length != 0 && buffer[ input_length - 1 ] == '\n' ) { buffer[ input_length - 1 ] = '\0'; --input_length; } result->name = malloc( input_length + 1 ); if( result->name == NULL ) { fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr ); free( result ); return NULL; } strcpy( result->name, buffer ); while( printf( "Nachname: " ), !fgets( buffer, sizeof( buffer ), stdin ) ) { fputs( "Eingabefehler, bitte wiederholen!\n", stderr ); clear_stdin(); } input_length = strlen( buffer ); if( input_length != 0 && buffer[ input_length - 1 ] == '\n' ) { buffer[ input_length - 1 ] = '\0'; --input_length; } result->surname = malloc( input_length + 1 ); if( result->surname == NULL ) { fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr ); free( result->name ); free( result ); return NULL; } strcpy( result->surname, buffer ); return result; } void free_customers( customer_t* customers[] ) { customer_t const** current_customer = customers; for( ; *current_customer != NULL; ++current_customer ) { free( (*current_customer)->name ); free( (*current_customer)->surname ); free( *current_customer ); } } /* - schreiben Sie eine Funktion, die die Kundenkartei ausgibt. Diese Funktion soll per "call by reference" das Kundenkartei-Array als Parameter bekommen. */ void print_customers( customer_t const* customers[] ) { customer_t const** current_customer = customers; puts( "Kundenkartei:\n" ); for( ; *current_customer != NULL; ++current_customer ) { printf( "Kd-Nr.: %u\nName: %s\nNachname: %s\n\n", (*current_customer)->id, (*current_customer)-> name, (*current_customer)->surname ); } } /* - schreiben Sie eine Funktion zum Suchen in der Kundenkartei. Diese Funktion bekommt die Kunden- Nummer und das Kundenkartei-Array als Parameter übergeben. Damit sucht sie in dem Array nach dem passenden Eintrag, indem sie mit Hilfe der Pointer indirekt auf die Datensätze der Kunden zugreift und die Kunden-Nummer vergleicht. Wenn der Datensatz mit der richtigen Nummer gefunden wurde, gibt die Funktion als Rückgabewert den Pointer dieses Datensatzes zurück. War die Suche erfolglos, soll ein NULLPointer zurückgegeben werden. */ customer_t const* find_customer( unsigned id, customer_t const* customers[] ) { customer_t const** current_customer = customers; for( ; *current_customer != 0; ++current_customer ) { if( (*current_customer)->id == id ) { return *current_customer; } } return NULL; } /* - deklarieren Sie als Vorlage für einen Buch-Datensatz einen weiteren struct-Datentyp, der z. B. buch heißt, mit den 4 Komponenten: Inventarnummer als Ganzzahl, Titel und Autor jeweils als String und den Ausleihvermerk als Pointer vom Typ kunde. */ typedef struct book_tag { unsigned id; char* title; char* author; customer_t const* borrower; } book_t; /* - schreiben Sie eine ähnliche Funktion zum Erfassen eines neuen Buches. Buch-Nummer, Autor und Titel werden vom Benutzer eingegeben. Der Ausleihvermerk soll zu NULL initialisiert werden, da das neue Buch ja noch nicht verliehen ist. */ book_t* create_book( unsigned id ) { char buffer[ MAX_BUFFER ]; book_t *result = NULL; size_t input_length = 0; if( ++id > MAX_BOOKS ) { return NULL; } result = malloc( sizeof( *result ) ); if( result == NULL ) { fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr ); return NULL; } result->id = id; result->borrower = NULL; clear_stdin(); while( printf( "Titel: " ), !fgets( buffer, sizeof( buffer ), stdin ) ) { fputs( "Eingabefehler, bitte wiederholen!\n", stderr ); clear_stdin(); } input_length = strlen( buffer ); if( input_length != 0 && buffer[ input_length - 1 ] == '\n' ) { buffer[ input_length - 1 ] = '\0'; --input_length; } result->title = malloc( input_length + 1 ); if( result->title == NULL ) { fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr ); free( result ); return NULL; } strcpy( result->title, buffer ); while( printf( "Autor: " ), !fgets( buffer, sizeof( buffer ), stdin ) ) { fputs( "Eingabefehler, bitte wiederholen!\n", stderr ); clear_stdin(); } input_length = strlen( buffer ); if( input_length != 0 && buffer[ input_length - 1 ] == '\n' ) { buffer[ input_length - 1 ] = '\0'; --input_length; } result->author = malloc( input_length + 1 ); if( result->author == NULL ) { fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr ); free( result->title ); free( result ); return NULL; } strcpy( result->author, buffer ); return result; } void free_books( book_t* books[] ) { book_t const** current_book = books; for( ; *current_book != NULL; ++current_book ) { free( (*current_book)->title ); free( (*current_book)->author ); free( *current_book ); } } /* - schreiben Sie eine ähnliche Funktion, die den Bücherkatalog ausgibt. Diese Funktion soll per "call by reference" das Katalog-Array als Parameter bekommen. */ void print_books( book_t* books[] ) { book_t **current_book = books; puts( "Buecherkatalog:\n" ); for( ; *current_book != NULL; ++current_book ) { printf( "Buch Nr.: %u", (*current_book)->id ); if( (*current_book)->borrower != NULL ) { printf( " ist zur Zeit ausgeliehen von \"%s %s\" (Kundennummer: %u)", (*current_book)->borrower->name, (*current_book)->borrower->surname, (*current_book)->borrower->id ); } printf( "\nTitel: %s\nAutor: %s\n", (*current_book)->title, (*current_book)->author ); } } /* - schreiben Sie analog dazu eine Funktion zum Suchen in dem Bücherkatalog. Diese Funktion bekommt die Buch-Nummer und das Buchkatalog-Array als Parameter übergeben. Ansonsten arbeitet diese Funktion wie die oben. */ book_t* find_book( unsigned id, book_t const* books[] ) { book_t const** current_book = books; for( ; *current_book != 0; ++current_book ) { if( (*current_book)->id == id ) { return (book_t*) *current_book; } } return NULL; } int main( void ) { /* - zur Verwaltung der Kunden-Daten dient ein Array, das Pointer auf die Datensätze enthält. Legen Sie ein Array von Pointern an, die auf den Datentyp kunde zeigen können. Dieses Array wird unsere Kundenkartei. Mit dessen Hilfe haben wir Zugriff auf alle Daten unserer Kunden. Initialisieren Sie das Array mit NULLPointern, da die Kundenkartei ja noch keine Einträge enthält. Die Größe des Arrays bestimmt die maximale Anzahl von Kunden. */ customer_t* customers[ MAX_CUSTOMERS + 1 ] = { NULL }; size_t num_customers = 0; /* - legen Sie analog dazu ein Array von Pointern an, die auf den Datentyp buch zeigen können. Initialisieren Sie auch dieses Array mit NULL-Pointern. Die Größe des Arrays bestimmt die maximale Anzahl von Büchern. Dieses Array ist der "Katalog". */ book_t* books[ MAX_BOOKS + 1 ] = { NULL }; size_t num_books = 0; int choice = 0; unsigned id = 0; customer_t const* found_customer = NULL; book_t* found_book = NULL; unsigned borrowers = 0; /* Das Programm soll eine einfache Menüsteuerung erhalten, die es dem Benutzer erlaubt, neue Kunden und Bücher einzugeben. Außerdem soll er eine Liste der Kunden oder Bücher anfordern können. Dabei soll das Programm erst dann beendet werden, wenn der Benutzer dies wünscht. */ /* - erweitern Sie das Menü für die Eingabe eines Verleihvorgangs und die Auflistung der verliehenen Bücher */ do { puts( " [1]\tNeuer Kunde\n [2]\tNeues Buch\n [3]\tKundenkartei auflisten\n [4]\tBuecherkatalog auflisten\n [5]\tBuch verleihen\n [6]\tVerliehene Buecher auflisten\n [0]\tProgramm beenden\n" ); if( ( choice = getchar() ) == '\n' ) { choice = getchar(); } puts( "\n\n" ); switch( choice ) { case '1': /* Neuer Kunde */ /* - mit jedem Aufruf der Funktion wird ein neuer Kunde angelegt und eine neue Position des Kundenkartei- Array beschrieben, so dass sich die Kartei sukzessive aufbaut. */ if( num_customers < MAX_CUSTOMERS ) { customers[ num_customers ] = create_customer( num_customers ); if( customers[ num_customers ] != NULL ) { num_customers++; } } else { fprintf( stderr, "\nDas Anlegen des Kunden ist fehlgeschlagen, da die Maximalanzahl verwaltbarer Kunden (%u) bereits erreicht ist!\n\n", MAX_CUSTOMERS ); } break; case '2': /* Neues Buch */ /* - mit jedem Aufruf dieser Funktion wird ein neues Buch in die Bibliothek aufgenommen und eine neue Position des Katalog-Array beschrieben, so dass sich der Katalog sukzessive aufbaut. */ if( num_books < MAX_BOOKS ) { books[ num_books ] = create_book( num_books ); if( books[ num_books ] != NULL ) { num_books++; } } else { fprintf( stderr, "\nDas Anlegen des Buches ist fehlgeschlagen, da die Maximalanzahl verwaltbarer Buecher (%u) bereits erreicht ist!\n\n", MAX_BOOKS ); } break; case '3': /* Kundenkartei auflisten */ print_customers( customers ); break; case '4': /* Buecherkatalog auflisten */ print_books( books ); break; case '5': /* Buch verleihen */ /* - bauen sie nun die Anweisungen für den Menüpunkt zum Ausleihen eines Buches ein: - dazu fordern Sie den Benutzer zur Eingabe der Kundennummer auf. Mit dieser Eingabe rufen Sie die Suchfunktion auf. Wird der Kunde gefunden, so bestätigt das Programm dies durch die Ausgabe des Namens. War die Suche erfolglos, wird der Fehler gemeldet und der Vorgang abgebrochen. - verfahren Sie genauso für die Eingabe des gewünschten Buches. - waren beide Eingaben erfolgreich, so kommt die bisher noch nicht benutzte Struktur-Komponente "Ausleihvermerk" des Buches ins Spiel. Sie soll anzeigen, wer (=Pointer auf den Kunden) das Buch ausgeliehen hat. Ist das Buch noch nicht ausgeliehen, so ist der Ausleihvermerk ein NULL-Pointer und Sie ersetzen diesen durch den Pointer auf den Kunden. Damit ist markiert, dass das Buch jetzt verliehen ist (Pointer ungleich NULL) und an wen (Pointer zeigt auf den Kunden). War der Vermerk jedoch schon gesetzt, so geben Sie eine Meldung aus, dass das Buch schon vergeben ist und sie brechen den Vorgang ab. */ while( puts( "Bitte geben Sie die Kundennummer ein:" ), scanf( "%u", &id ) != 1 || id == 0 ) { fputs( "Eingabefehler, bitte wiederholen!\n", stderr ); clear_stdin(); } found_customer = find_customer( id, customers ); if( found_customer == NULL ) { fprintf( stderr, "Es existiert kein Kunde mit Kundennummer %u!\n", id ); break; } printf( "\nDer Kunde \"%s %s\" wurde unter der Kundennummer %u gefunden.\n\n", found_customer->name, found_customer->surname, found_customer-> id ); while( puts( "Bitte geben Sie die Buchnummer ein:" ), scanf( "%u", &id ) != 1 || id == 0 ) { fputs( "Eingabefehler, bitte wiederholen!\n", stderr ); clear_stdin(); } found_book = find_book( id, books ); if( found_customer == NULL ) { fprintf( stderr, "Es existiert kein Buch mit Buchnummer %u!\n", id ); break; } printf( "\nDas Buch \"%s\" wurde unter der Buchnummer %u gefunden.\n\n", found_book->title, found_book-> id ); if( found_book->borrower != NULL ) { printf( "Das Buch \"%s\" (Nummer: %u) wurde bereits vom Kunden \"%s %s\" (Kundennummer: %u) ausgeliehen.\n\n", found_book->title, found_book->id, found_book->borrower->name, found_book->borrower->surname, found_book->borrower->id ); } else { found_book->borrower = found_customer; printf( "Das Buch \"%s\" (Nummer: %u) ist nun als vom Kunden \"%s %s\" (Kundennummer: %u) ausgeliehen markiert.\n\n", found_book->title, found_book->id, found_book->borrower->name, found_book->borrower->surname, found_book->borrower->id ); } break; case '6': /* Verliehene Buecher auflisten */ /* - bauen Sie schließlich die Anweisungen für den Menüpunkt zum Auflisten der verliehenen Bücher ein. Dazu durchsuchen Sie den Katalog und schauen nach den Ausleihvermerken. Ist ein Kunde als Ausleiher vermerkt, so geben Sie das Buch und den Kunden aus. Außerdem zählen Sie die Anzahl der gefundenen Einträge und geben das Ergebnis zum Schluss aus. */ for( id = 0, borrowers = 0; books[ id ]; ++id ) { if( books[ id ]->borrower != NULL ) { printf( "Buch Nr.: %u ist zur Zeit ausgeliehen von \"%s %s\" (Kundennummer: %u)\n", books[ id ]->id, books[ id ]->borrower->name, books[ id ]->borrower->surname, books[ id ]->borrower->id ); ++borrowers; } } printf( "\nInsgesamt sind %u Buecher verliehen.\n", borrowers ); break; case '0': /* Programm beenden */ puts( "\nDas Programm wird beendet.\n" ); break; default: fputs( "Eingabefehler, bitte wiederholen!\n", stderr ); } puts( "\n\n" ); } while( choice != '0' ); free_books( books ); free_customers( customers ); }
-
Das nenn ich mal eine Antwort,
ehrlich gesagt bin ich einbisschen sprachlos(im positiven Sinne)Danke vielmals ich weiß die Mühe zu schätzen
jetzt heißt es erstmal alle Schritte durchlesen und verstehen