if-struct-pointer



  • #include <stdio.h>
    #include <string.h>
    

    denk' ich mir jetzt mal dazu.

    Es heißt int main( void ) . Sagt dir das dein Compiler nicht?
    Ab x = 1 in Ausleihliste dereferenzierst du Nullpointer.
    Ausgegeben wird nichts, da kunde::cdn_Nr nie etwas anderes als 0 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


  • Mod

    Swordfish schrieb:

    Es heißt int main( void ) . Sagt dir das dein Compiler nicht?

    Wieso? main() ist absolut kompatibel mit int 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 soll kdn_Nr etwas anderes als 0 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 vergeben

    arr_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 werden

    Wenn 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-pointer

    mit 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



  • #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 );
    }
    
    char* my_getline( char const* request )
    {
    	char buffer[ MAX_BUFFER ];
    	char ch = 0;
    	size_t input_length = 0;
    	char *result = NULL;
    
    	while( request && printf( "%s", request ), !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 = malloc( input_length + 1 );
    
    	if( !result ) return NULL;
    
    	return strcpy( result, buffer );
    }
    
    unsigned my_get_uint( char const* request )
    {
    	unsigned result = 0;
    
    	while( printf( "%s", request ), scanf( "%u", &result ) != 1 ) {
    
    		fputs( "Eingabefehler, bitte wiederholen!\n", stderr );
    		clear_stdin();
    	}
    
    	return result;
    }
    
    typedef struct customer_tag {
    
    	unsigned id;
    	char* name;
    	char* surname;
    
    } customer_t;
    
    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;
    
    	if( !( ( result = malloc( sizeof( *result ) ) ) && ( result->name = my_getline( "Name:     " ) ) && ( result->surname = my_getline( "Nachname: " ) ) ) ) {
    
    		fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr );
    
    		if( result )
    			free( result->name );
    
    		free( result );
    		return NULL;
    
    	} else result->id = id;
    
    	return result;
    }
    
    void free_customers( customer_t* customers[] )
    {
    
    	customer_t const** current_customer = customers;
    
    	for( ; *current_customer; ++current_customer ) {
    
    		free( (*current_customer)->name );
    		free( (*current_customer)->surname );
    		free( *current_customer );
    	}
    }
    
    void print_customers( customer_t const* customers[] )
    {
    	customer_t const** current_customer = customers;
    
    	puts( "Kundenkartei:\n" );
    
    	for( ; *current_customer; ++current_customer )
    		printf( "Kd-Nr.:   %u\nName:     %s\nNachname: %s\n\n", (*current_customer)->id, (*current_customer)-> name, (*current_customer)->surname );
    }
    
    customer_t const* find_customer( unsigned id, customer_t const* customers[] )
    {
    	customer_t const** current_customer = customers;
    
    	for( ; *current_customer; ++current_customer )
    		if( (*current_customer)->id == id )
    			return *current_customer;
    
    	return NULL;
    }
    
    typedef struct book_tag {
    
    	unsigned id;
    	char* title;
    	char* author;
    	customer_t const* borrower;
    
    } book_t;
    
    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;
    
    	if( !( ( result = malloc( sizeof( *result ) ) ) && ( result->title = my_getline( "Titel:    " ) ) && ( result->author = my_getline( "Autor:    " ) ) ) ) {
    
    		fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr );
    
    		if( result )
    			free( result->title );
    
    		free( result );
    
    		return NULL;
    
    	} else {
    
    		result->id = id;
    		result->borrower = NULL;
    	}
    
    	return result;
    }
    
    void free_books( book_t* books[] )
    {
    	book_t const** current_book = books;
    
    	for( ; *current_book; ++current_book ) {
    
    		free( (*current_book)->title );
    		free( (*current_book)->author );
    		free( *current_book );
    	}
    }
    
    void print_books( book_t* books[], unsigned only_borrowed )
    {
    	book_t **current_book = books;
    	unsigned borrowers = 0;
    
    	puts( "Buecherkatalog:\n" );
    
    	for( ; *current_book; ++current_book ) {
    
    		if( !only_borrowed || ( only_borrowed && (*current_book)->borrower ) ) {
    
    			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 );
    				++borrowers;
    			}
    
    			printf( "\nTitel:    %s\nAutor:    %s\n\n", (*current_book)->title, (*current_book)->author );
    		}
    	}
    
    	printf( "Insgesamt sind %u Buecher verliehen.\n", borrowers );
    }
    
    book_t* find_book( unsigned id, book_t const* books[] )
    {
    	book_t const** current_book = books;
    
    	for( ; *current_book; ++current_book )
    		if( (*current_book)->id == id )
    			return (book_t*) *current_book;
    
    	return NULL;
    }
    
    int main( void )
    {
    	customer_t* customers[ MAX_CUSTOMERS + 1 ] = { NULL };
    	size_t num_customers = 0;
    
    	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;
    
    	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" );
    		choice = scanf( " %u", &choice ) == 1 ? choice : UINT_MAX;
    		clear_stdin();
    		puts( "\n\n" );
    
    		switch( choice ) {
    
    			case 1:	/* Neuer Kunde */
    
    				if( num_customers < MAX_CUSTOMERS && ( customers[ num_customers ] = create_customer( num_customers ) ) ) ++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 */
    
    				if( num_books < MAX_BOOKS && ( books[ num_books ] = create_book( num_books ) ) ) ++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, 0 );
    				break;
    
    			case 5:	/* Buch verleihen */
    
    				if( !( found_customer = find_customer( id = my_get_uint( "Bitte geben Sie die Kundennummer ein:" ), customers ) ) ) {
    
    					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 );
    
    				if( !( found_book = find_book( id = my_get_uint( "Bitte geben Sie die Buchnummer ein:" ), books ) ) ) {
    
    					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 ) {
    
    					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 */
    
    				print_books( books, 1 );
    				break;
    
    			case 0:	/* Programm beenden */
    
    				puts( "\nDas Programm wird beendet.\n" );
    				break;
    
    			default:
    				fputs( "Eingabefehler, bitte wiederholen!\n", stderr );
    		}
    
    		puts( "\n\n" );
    
    	} while( choice );
    
    	free_books( books );
    	free_customers( customers );
    }
    

    gekürzt.



  • spagetti schrieb:

    Das nenn ich mal eine Antwort,
    ehrlich gesagt bin ich einbisschen sprachlos(im positiven Sinne)

    Ich nicht.
    Und das im negativen Sinne.
    Viel zu viel Code für die kleine Aufgabe und fehlerhaft und standardinkonform obendrein.



  • ob man mit seiner Arbeit zufrieden ist, liegt wiederum im Auge des Betrachters,
    darüber könnte man philosophieren
    ich bin noch ein Programmier-Jüngling, deshalb bin ich schon zufrieden, wenn die Haupteile der Prgramme funktionieren

    kann mich nur nochmals bei dir bedanken


Anmelden zum Antworten