richtiger Funktionsaufruf



  • Achte auf die Compilerwarnungen

    char sort(struct element *list_begin,struct element *tmpPointer)
    {...
        printf("%p\n",list_begin);
        return list_begin;  //  list_begin ist kein char
    
    }
    

    und in der main:

    sort(list_begin,tmpPointer); // Rückgabewert?
    

    Der Rückgabetyp bei der Definition und beim return passen nicht zusammen.
    Zudem wertest du den ja auch gar nicht aus.



  • So etwa?

    struct element* sort(struct element*, struct element*);
    ...
    struct element* sort(struct element *list_begin,struct element *tmpPointer)
    {
    ...
        return list_begin;
    }
    

    Mein compiler (gcc in CodeBlocks) gibt mir außer ein paar Warnungen zu impliziten Deklarationen zu Funktionen wie strlen, strcpy etc sonst nichts zurück.
    Sorry, dass ich da grade so schwer von Begriff bin..



  • rei0d schrieb:

    Mein compiler (gcc in CodeBlocks) gibt mir außer ein paar Warnungen zu impliziten Deklarationen zu Funktionen wie strlen, strcpy etc sonst nichts zurück.

    Dann geh mal ins Menue Project -> Build Options ... und da auf den Reiter Compiler Settings.
    Da machst du je einen Haken bei "Enable all compiler warnings [-Wall]" und "Enable extra compiler warnings [-Wextra]"

    Und ein #include <string.h> solltest du noch spendieren.

    Dein Programm muss ohne Warnungen compilieren.



  • Danke für den Tipp mit den Compilerwarnungen, jetzt zeigt er wirklich mehr an, was enorm hilfreich ist.
    Ich habe jetzt den ganzen Code entsprechend der Aufgabenstellung überarbeitet und alles zum Laufen bekommen, d.h. das Einsortieren, Ausgeben und Suchen in einzelne Funktionen gepackt. Fehler oder Warnungen bekomme ich auch keine mehr angezeigt.
    Danke für die Hilfe, ich war zeitweise wirklich schwer von Begriff.

    PS:
    Ich habe nicht bedacht, dass der Pointer list_begin, den ich in einer Funktion ändere, ja sich global nicht ändert, das war eigentlich mein größter Denkfehler.

    PPS: Hier mein Quellcode:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MaxCharPerLine 51
    
    struct element
    {
        char *list0;
        struct element *next;
    };
    
    struct element* sort(struct element*, struct element*);
    void printAll(struct element*);
    int searchForString(struct element*, char*);
    
    int main ()
    {
    
        /* Zeiger auf Anfang der Liste */
        struct element *list_begin = NULL;
        /* Temporaerer Zeiger auf Listenknoten */
        struct element *tmpPointer;
    
        char t[MaxCharPerLine];
    
        int tlen = 0;
        int cnt = 0;
        int repeat = 1;
        char search[MaxCharPerLine];
    
        /* Einlesen in list0 */
        while(fgets(t, sizeof(t), stdin)!=NULL)
        {
            tlen = strlen(t);
            if(tlen == 1)
            {
                continue;
            }
            char *s = calloc(tlen + 1,sizeof(char));
            if(t[tlen - 1]=='\n')
            {
                t[tlen - 1]='\0';
            }
    
            strcpy(s,t);
    
            cnt++;
            /* Speicher anfordern */
            tmpPointer = (struct element *)malloc(sizeof (struct element));
    
            /* Daten in list0 eintragen */
            tmpPointer -> list0 = s;
            tmpPointer -> next = NULL;
    
            printf("%p %p\n",list_begin,tmpPointer);
            list_begin = sort(list_begin,tmpPointer);
        }
    
        printAll(list_begin);
    
        /* Freigeben von stdin, sodass Eingabe über Tastatur erfolgen kann */
        freopen("/dev/tty","r",stdin);
    
        while(repeat)
        {
            printf("Gesuchte Zeichenkette: ");
            fgets(search,MaxCharPerLine,stdin);
            /* fgets() liest '\n\0' als letzte Zeichen ein, '\n' muss aber weg für strstr() */
            search[strlen(search) - 1] = '\0';
    
            cnt = searchForString(list_begin,search);
            puts("\t|------------------------------------|");
            printf("\t|\t%i Objekt(e) gefunden.\t     |\n",cnt);
            puts("\t|------------------------------------|");
        }
        free(tmpPointer);
    
        return 0;
    
    }
    struct element* sort(struct element *list_begin,struct element *tmpPointer)
    {
        struct element *currentPointer = list_begin;
    
        /* Sortieren */
    
        if(list_begin == NULL)
        {
            list_begin = tmpPointer;
        }
        else
        {
    
            if(strcmp(list_begin->list0, tmpPointer->list0) > 0)
            {
                tmpPointer->next = list_begin;
                list_begin = tmpPointer;
            }
            else
            {
    
                while((currentPointer->next) != NULL)
                {
                    if(strcmp((currentPointer->next)->list0, tmpPointer->list0) > 0)
                    {
                        break;
                    }
                    currentPointer = currentPointer->next;
                }
    
                tmpPointer->next = currentPointer->next;
                currentPointer->next = tmpPointer;
            }
        }
        return list_begin;
    
    }
    
    void printAll(struct element *list_begin)
    {
        struct element *tmpPointer;
    
        tmpPointer = list_begin;
    
        while (tmpPointer != NULL)
        {
    
            printf("%s\n", tmpPointer->list0);
    
            /* Zeiger auf nächsten Eintrag */
            tmpPointer = tmpPointer->next;
    
        }
    }
    
    int searchForString(struct element *list_begin,char *search)
    {
        int cnt = 0;
        struct element *currentPointer;
        struct element *beforePointer;
        int found = 0;
        int number = 0;
    
        currentPointer = list_begin;
        beforePointer = NULL;
        while(currentPointer != NULL)
        {
            number++;
            if(strstr((currentPointer->list0),search))
            {
                /* Übereinstimmung */
                found = 1;
            }
            /* vorheriges Element merken */
            beforePointer = currentPointer;
            if(found == 1)
            {
                cnt++;
                if(beforePointer == NULL)
                {
                    /* Erstes Element gefunden */
                    printf("%i: %s\n",number,list_begin->list0);
    
                    /* Gefundenes Element löschen */
                    //list_begin = currentPointer->next;
                }
    
                else
                {
                    printf("%i: %s\n",number,currentPointer->list0);
                    /* Löschen des gefundenen Elements */
                    //beforePointer->next = currentPointer->next;
    
                }
    
            }
            found = 0;
            currentPointer = currentPointer->next;
    
        }
        number = 0;
    
        return cnt;
    }
    

  • Mod

    Wäre es nicht auch schön, wenn man das Programm beenden könnte, ohne es abzuschießen? Dann könntest du auch üben, wie man Speicher richtig freigibt. Mit deinem einem free, welches zudem nie erreicht wird, ist es nämlich nicht getan.



  • Ok, jetzt beendet es, wenn EOF erfüllt ist.

    ...
    while(printf("Suchen nach: ") && fgets(search,sizeof(search),stdin) != NULL)
        {
            /* fgets() liest '\n\0' als letzte Zeichen ein, '\n' muss aber weg für strstr() */
            search[strlen(search) - 1] = '\0';
            cnt = searchForString(list_begin,search);
            puts("\t|------------------------------------|");
            printf("\t|\t%i Objekt(e) gefunden.\t     |\n",cnt);
            puts("\t|------------------------------------|");
        }
    ...
    

    Um die Liste zu löschen müsste doch folgendes klappen oder?

    ...
    /* Zeiger auf Anfang der Liste */
        struct element *list_begin = NULL;
        /* Temporaerer Zeiger auf Listenknoten */
        struct element *tmpPointer;
        struct element *freePointer = NULL;    
    ...
    tmpPointer = list_begin;
    
        while(tmpPointer!=NULL)
        {
            freePointer = tmpPointer;
            tmpPointer = tmpPointer->next;
            free(freePointer->list0);
            free(freePointer);
    
        }
        free(tmpPointer);
    ...
    


  • s musst du ganz am Schluss wieder freigeben; genauso übrigens alle Listenelemente!

    dein free(tmpPointer) in Zeile 77 macht übrigens nicht das was du vermutlich willst; es wird nämlich lediglich das letzte Element aus der Liste an free übergeben, alle anderen Elemente bleiben im Speicher!



  • rei0d schrieb:

    Eigentlich müsste ich ja noch s freigeben, mit einem free(s) meckert aber der Compiler. Gibt es sonst noch eine Möglichkeit?

    Achte auf den Scope von s. Die Pointervariable s ist nur innerhalb der while-Schleife gültig.

    Allerdings übernimmt doch tmpPointer->list0 den Bereich von s.



  • Ich habe meinen letzten Beitrag schon dahingehend editiert, jetzt müsste er ja die gesamte Liste löschen oder?



  • Sollte funktionieren. Aber das free in Zeile 18 ist überflüssig. Das Element wird in der Schleife schon freigegeben.


Anmelden zum Antworten