Kritik. bitte.



  • Aufgabenstellung:

    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.
    

    Lösungsvorschlag:

    #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 );
    }
    

    Wutz schrieb:

    Viel zu viel Code für die kleine Aufgabe und fehlerhaft und standardinkonform obendrein.

    Möchte das bitte jemand etwas detaillierter ausführen?


  • Mod

    Viel zu viel Code zum kommentieren.
    Ein #include <limits.h> fehlt.
    Einige unsichere Konvertierungen der Form T** -> const T**
    das ist in C allerdings erlaubt.



  • - memory.h ist kein Standard
    - my_get_uint scheitert bei simplen Nutzerfehleingaben (für z.B. Kunden/Buchnummer 123a schlägt das 'a' durch auf den folgenden Programmablauf)



  • Viel weniger Code, dafür strikt konform (bis auf eine Stelle, wobei ich bezweifle, dass du sie findest).

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
      struct kunde {int nr;char vname[100],nname[100];} *kartei[100];
      struct buch {int nr;char titel[100],autor[100];struct kunde *ausleih;} *katalog[100];
      int kz,bz;
    } Datenbank;
    
    int eingabe(int *z,int *nr,char *s1,char *s2,const char *text)
    {
      char s[300];
      printf("\n%s: ",text);
      if( fgets(s,300,stdin) && sscanf(s,"%99s%99s",s1,s2)==2 )
        *nr=++*z;
      if(!strchr(s,'\n')){ int c; while( (c=getchar())!='\n' && c!=EOF ); }
      return *nr;
    }
    
    int eingabeNr(char *s)
    {
      int r;
      printf(s);
      if( 1!=scanf("%d",&r) || r<1 ) r=0;
      { int c; while( (c=getchar())!='\n' && c!=EOF ); }
      return r;
    }
    
    void ausgabe(void *liste,int z)
    {
      struct {int i;char str1[100],str2[100];} **l=liste;
      while( z-- )
        printf("%3d%15s%15s\n",l[z]->i,l[z]->str1,l[z]->str2);
    }
    
    void dbfree(Datenbank *db)
    {
      while( db->kz-- ) free(db->kartei[db->kz]);
      while( db->bz-- ) free(db->katalog[db->bz]);
    }
    
    int main()
    {
      Datenbank db={0};
      char str[BUFSIZ];
    
      while(1)
      switch( puts( "\n [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 sonst\tProgramm beenden\n" ),
             fgets(str,BUFSIZ,stdin),
             *str ) {
    
      case '1': if( db.kz<100 ) if( db.kartei[db.kz]=calloc(1,sizeof(**db.kartei)),
                    !eingabe(&db.kz,&db.kartei[db.kz]->nr,db.kartei[db.kz]->vname,db.kartei[db.kz]->nname,"Eingabe-Kunde: Vorname Nachname") )
                    puts("Eingabe fehlerhaft"),free(db.kartei[db.kz]);
                break;
      case '2': if( db.bz<100 ) if( db.katalog[db.bz]=calloc(1,sizeof(**db.katalog)),
                    !eingabe(&db.bz,&db.katalog[db.bz]->nr,db.katalog[db.bz]->titel,db.katalog[db.bz]->autor,"Eingabe-Buch: Titel Autor") )
                    puts("Eingabe fehlerhaft"),free(db.katalog[db.bz]);
                break;
      case '3': ausgabe(db.kartei,db.kz);break;
      case '4': ausgabe(db.katalog,db.bz);break;
      case '5': { int kundenr=eingabeNr("KundeNr: ");
                  if( kundenr && kundenr<=db.kz )
                  {
                    int buchnr=eingabeNr("BuchNr: ");
                    if( buchnr && buchnr<=db.bz )
                    {
                      db.katalog[buchnr-1]->ausleih=db.kartei[kundenr-1];
                      break;
                    }
                  }
                  puts("KundeNr oder BuchNr fehlerhaft");
                  break;
                }
      case '6': { int i;
                  for(i=0;i<db.bz;++i)
                    if( db.katalog[i]->ausleih )
                      printf("%3d%15s%15s: %3d%15s%15s\n",db.katalog[i]->nr,db.katalog[i]->titel,db.katalog[i]->autor,
                                                      db.katalog[i]->ausleih->nr,db.katalog[i]->ausleih->vname,db.katalog[i]->ausleih->nname);
                  break;
                }
      default: dbfree(&db);exit(0);
      }
      return 0;
    }
    


  • Wutz schrieb:

    Viel weniger Code, dafür strikt konform (bis auf eine Stelle, wobei ich bezweifle, dass du sie findest).

    Mag' ich garnicht finden. Dein Code verschluckt sich schon am Enter nach der eingabe von 1 zur Auswahl einen neuen Kunden anzulegen.

    @camper: guck' ich mir an, wie auch memory.h vs. stdlib.h.



  • [cpp
    fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr );

    if( result )
    free( result->title );

    free( result );

    return NULL;
    [/cpp]

    fputs( "Nicht genuegend freier Arbeitsspeicher verfuegbar!", stderr );
    
            if( result ) {
                if (result->title)
                     free( result->title );
    
                free( result );
            }
    
            return NULL;
    

    @Wutz: So einen unübersichtlichen Code möchte auch keiner lesen. 😉



  • @Swordfish: Benutze mal indent, um den Code schöner einzurücken, falls du Unix hast.

    EDIT: Hab den Code von Swordfish mit dem vom Wutz verwechselt.^^



  • Was ist an meinen Einrückungen kaputt? 😕



  • Och, so schlimm ist Wutz's code gar nich 😛
    Was ich schon gesehen hab, da is Wutz's seiner harmlos. ^^



  • Hab das gerade mal getestet - theoretisch sah das gut aus.

    Das der Kommentar des Compilers zum 1.Quelltext:
    Zu den Zeileangaben 3 hinzuaddieren.

    >gcc -pedantic -Os -o dbbuc002 dbbuc002.c  -std=c11
    dbbuc002.c: In function 'free_customers':
    dbbuc002.c:100:43: warning: initialization from incompatible pointer type [enabled by default]
    dbbuc002.c:106:9: warning: passing argument 1 of 'free' discards 'const' qualifier from pointer target type [enabled by default]
    In file included from dbbuc002.c:5:0:
    c:\mingw470\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/stdlib.h:358:38: note: expected 'void *' but argument is of type 'const struct customer_t *'
    dbbuc002.c: In function 'free_books':
    dbbuc002.c:175:35: warning: initialization from incompatible pointer type [enabled by default]
    dbbuc002.c:181:9: warning: passing argument 1 of 'free' discards 'const' qualifier from pointer target type [enabled by default]
    In file included from dbbuc002.c:5:0:
    c:\mingw470\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/stdlib.h:358:38: note: expected 'void *' but argument is of type 'const struct book_t *'
    dbbuc002.c: In function 'main':
    dbbuc002.c:241:58: error: 'UINT_MAX' undeclared (first use in this function)
    dbbuc002.c:241:58: note: each undeclared identifier is reported only once for each function it appears in
    dbbuc002.c:263:17: warning: passing argument 1 of 'print_customers' from incompatible pointer type [enabled by default]
    dbbuc002.c:111:6: note: expected 'const struct customer_t **' but argument is of type 'struct customer_t **'
    dbbuc002.c:275:17: warning: passing argument 2 of 'find_customer' from incompatible pointer type [enabled by default]
    dbbuc002.c:122:19: note: expected 'const struct customer_t **' but argument is of type 'struct customer_t **'
    dbbuc002.c:283:17: warning: passing argument 2 of 'find_book' from incompatible pointer type [enabled by default]
    dbbuc002.c:214:9: note: expected 'const struct book_t **' but argument is of type 'struct book_t **'
    

    Das zum 2.Quelltext: Compiler wie oben, war zufrieden.
    Dann hab ich versucht Johann Sebastian Bach als Kunde anzulegen - Ein bekannter Komponist - ist wohl schon zu lange her das der in Leipzig und Umgebung tätig war.

    Und so ein schlechter Roman mit dem Titel: "Das Grauen des Waldes" geschrieben von der "Schreiber BGB Müller, Maier und Companion" lies sich auch nicht speichern, obwohl für die Anzahl der Zeichen genug Platz vorgehalten wurde.
    Ist vielleicht auch ganz gut so, das der nicht ausgeliehen werden kann.



  • Swordfish schrieb:

    Was ist an meinen Einrückungen kaputt? 😕

    Dein Code war nicht gemeint.

    itedvo schrieb:

    Och, so schlimm ist Wutz's code gar nich 😛
    Was ich schon gesehen hab, da is Wutz's seiner harmlos. ^^

    Ich auch, aber:

    Wutz schrieb:

    Viel weniger Code, dafür strikt konform (bis auf eine Stelle, wobei ich bezweifle, dass du sie findest).

    Klingt für mich irgendwie etwas arrogant. Oder täusche ich mich da?
    Zumal er gar keine Funktionsargumente auf Gültigkeit überprüft (z. B. Zeiger).



  • Kritik:
    - bitte keine so langen Aufgabenstellungen posten
    - bitte keinen so langen sourcecode posten
    - bitte die Aufgabe erst selbst angehen
    - bitte nur dann die kritischen Fragen gezielt mit wenig sourcecode stellen
    😞


Anmelden zum Antworten