richtiger Funktionsaufruf



  • Hallo Leute,
    ich soll ein Programm, das ich geschrieben habe, noch in einzelne Funktionen aufteilen, Vorlesungen dazu, wie das aber genau mit Übergabeparametern funktioniert, hatten wir nicht. Die Einträge dazu von galileocomputing.de waren zwar eine Hilfe beim Verständnis, so ganz dahinter gestiegen bin ich aber noch nicht.
    Also mein Programm soll aus einer Textdatei Einträge einlesen und mit Pointern sortieren. Das klappt auch soweit durch die Hilfe von einigen hier im Forum. Jetzt sollen zusätzlich noch folgende Funktionen erstellt werden:

    - Eine zum Einlesen der Elemente und gleichzeitiges sortieren deren Übergabeparameter: aktuelle Adresse des Listenanfangs, bei mir list_begin->list0 und die Adresse des neuen Elements, bei mir currentPointer->list0
    Rückgabewert: Adresse des evt. veränderten Listenanfangs, also return list_begin->list0

    - Ausgabe der verketteten Liste
    Übergabeparameter: Adresse des Listenanfangs, bei mir wieder list_begin->list0
    Kein Rückgabewert

    - Durchsuchen der Zeichenkette nach einem bestimmten Teilstring und Ausgabe davon in der Kommandozeile
    Übergabeparameter: Adresse des Listenanfangs, wieder list_begin->list0 und Adresse der gesuchten Zeichenkette
    Rückgabewert: Anzahl der gefundenen Zeichenketten

    Eins vorab, wir sollen eine verkette Liste benutzen und die Funktionen so verwenden, wie sie gegeben sind, egal wie sinnvoll das jetzt ist oder nicht.

    Da ja alle Anforderungen schon funktionieren und diese lediglich alle in der main-Funktion sind, anstatt einzeln definiert zu sein, müsste ich doch lediglich kurz eine neue Funktion definieren, diese aufrufen und dann den Quellcode in die neue Funktion kopieren oder? Ich müsste ja nur wegen den Übergabeparametern aufpassen oder?

    Ich habe mir das wie folgt gedacht:

    Definition der Funktion für das sortiere Einfügen:

    int insert(struct element,struct element);
    

    Funktionsaufruf für das sortierte Einfügen am Anfang der main Funktion:

    insert(list_begin->list0,currentPointer->list0);
    

    gesamter Quellcode mit Funktionen:

    #include <stdio.h>
    #include <stdlib.h>
    #define MaxCharPerLine 51
    
    /* Zeiger auf Anfang und Ende der Liste */
    struct element *list_begin = NULL;
    struct element *list_end = NULL;
    
    /* Temporaerer Zeiger auf Listenknoten */
    struct element *tmpPointer;
    /* Zeiger auf aktuelles Element */
    struct element *currentPointer;
    /* Zeifer auf vorheriges Element */
    struct element *beforePointer;
    
    char tmpSearch1[MaxCharPerLine];
    char tmpSearch2[MaxCharPerLine];
    
    char t[MaxCharPerLine];
    
    int tlen = 0;
    int cnt = 0;
    char s[MaxCharPerLine];
    char search[MaxCharPerLine];
    int i = 0;
    int j = 0;
    int found = 0;
    int number = 0;
    int repeat = 1;
    
    struct element
    {
        char *list0;
        struct element *next;
    };
    
    int insert(struct element, struct element);
    
    int main ()
    {
    
        insert(list_begin->list0,currentPointer->list0);
    
        /* Ausgabe von list0 */
        tmpPointer = list_begin;
    
        while (tmpPointer != NULL)
        {
    
            printf ("%s\n", tmpPointer -> list0);
    
            /* Zeiger auf nächsten Eintrag */
            tmpPointer = tmpPointer -> next;
    
        }
    
        /* Freigeben von stdin, sodass Eingabe über Tastatur erfolgen kann */
        freopen("/dev/tty","r",stdin);
    
        /* Suche nach Teilkette */
        while(repeat)
        {
            printf("Gesuchte Zeichenkette: ");
            scanf("%s",&search);
            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)
                {
                    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;
    
        }
    
        free(tmpPointer);
    
        return 0;
    }
    
    int insert(struct element list_begin,struct element currentPointer)
    {
    
        /* Einlesen in list0 */
        while(fgets(t, sizeof(t), stdin)!=NULL)
        {
            tlen = strlen(t);
            if(tlen == 1)
            {
                free(s);
                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;
    
            /* Sortieren */
            currentPointer = list_begin;
    
            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->list0;
    }
    

    Quellcode ohne Funktionen(alles funktioniert):

    #include <stdio.h>
    #include <stdlib.h>
    #define MaxCharPerLine 51
    
    struct element
    {
        char *list0;
        struct element *next;
    };
    
    int main ()
    {
    
        /* Zeiger auf Anfang und Ende der Liste */
        struct element *list_begin = NULL;
        struct element *list_end = NULL;
    
        /* Temporaerer Zeiger auf Listenknoten */
        struct element *tmpPointer;
        /* Zeiger auf aktuelles Element */
        struct element *currentPointer;
        /* Zeifer auf vorheriges Element */
        struct element *beforePointer;
    
        char tmpSearch1[MaxCharPerLine];
        char tmpSearch2[MaxCharPerLine];
    
        char t[MaxCharPerLine];
    
        int tlen = 0;
        int cnt = 0;
        char s[MaxCharPerLine];
        char search[MaxCharPerLine];
        int i = 0;
        int j = 0;
        int found = 0;
        int number = 0;
        int repeat = 1;
    
        /* Einlesen in list0 */
        while(fgets(t, sizeof(t), stdin)!=NULL)
        {
            tlen = strlen(t);
            if(tlen == 1)
            {
                free(s);
                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;
    
            /* Sortieren */
            currentPointer = list_begin;
    
            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;
                }
            }
        }
    
        /* Ausgabe von list0 */
        tmpPointer = list_begin;
    
        while (tmpPointer != NULL)
        {
    
            printf ("%s\n", tmpPointer -> list0);
    
            /* Zeiger auf nächsten Eintrag */
            tmpPointer = tmpPointer -> next;
    
        }
    
        /* Freigeben von stdin, sodass Eingabe über Tastatur erfolgen kann */
        freopen("/dev/tty","r",stdin);
    
        /* Suche nach Teilkette */
        while(repeat)
        {
            printf("Gesuchte Zeichenkette: ");
            scanf("%s",&search);
            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)
                {
                    if(beforePointer == NULL)
                    {
                        /* Erstes Element gefunden */
                        printf("%i: %s\n",number,list_begin->list0);
                    }
                    else
                    {
                        printf("%i: %s\n",number,currentPointer->list0);
                    }
    
                }
                found = 0;
                currentPointer = currentPointer->next;
    
            }
            number = 0;
    
        }
        free(tmpPointer);
    
        return 0;
    }
    

    Wo liegen da meine (Denk-)Fehler? Geht das überhaupt so einfach, alles einfach zu kopieren?



  • Die Übergabeparameter müssen Zeiger sein:

    int insert(struct element *list_begin, struct element *currentPointer)
    

    P.S. Und den Rückgabetyp solltest du auch noch mal überprüfen.



  • Danke für die schnelle Antwort und für den Tipp!
    Hab das jetzt wie folgt abgeändert, bekomme aber immernoch einen Fehler, bei der Funktion insert()(Zeile 118), wegen in Konflikt stehenden Typen. Hast du dazu noch einen Tipp oder Hinweis?

    #include <stdio.h>
    #include <stdlib.h>
    #define MaxCharPerLine 51
    
    /* Zeiger auf Anfang und Ende der Liste */
    struct element *list_begin = NULL;
    struct element *list_end = NULL;
    
    /* Temporaerer Zeiger auf Listenknoten */
    struct element *tmpPointer;
    /* Zeiger auf aktuelles Element */
    struct element *currentPointer;
    /* Zeifer auf vorheriges Element */
    struct element *beforePointer;
    
    char tmpSearch1[MaxCharPerLine];
    char tmpSearch2[MaxCharPerLine];
    
    char t[MaxCharPerLine];
    
    int tlen = 0;
    int cnt = 0;
    char s[MaxCharPerLine];
    char search[MaxCharPerLine];
    int i = 0;
    int j = 0;
    int found = 0;
    int number = 0;
    int repeat = 1;
    
    struct element
    {
        char *list0;
        struct element *next;
    };
    
    int insert(struct element, struct element);
    
    int main ()
    {
    
        insert(*list_begin,*currentPointer);
    
        /* Ausgabe von list0 */
        tmpPointer = list_begin;
    
        while (tmpPointer != NULL)
        {
    
            printf ("%s\n", tmpPointer -> list0);
    
            /* Zeiger auf nächsten Eintrag */
            tmpPointer = tmpPointer -> next;
    
        }
    
        /* Freigeben von stdin, sodass Eingabe über Tastatur erfolgen kann */
        freopen("/dev/tty","r",stdin);
    
        /* Suche nach Teilkette */
        while(repeat)
        {
            printf("Gesuchte Zeichenkette: ");
            scanf("%s",&search);
            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)
                {
                    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;
    
        }
    
        free(tmpPointer);
    
        return 0;
    }
    
    int insert(struct element *list_begin,struct element *currentPointer)
    {
    
        /* Einlesen in list0 */
        while(fgets(t, sizeof(t), stdin)!=NULL)
        {
            tlen = strlen(t);
            if(tlen == 1)
            {
                free(s);
                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;
    
            /* Sortieren */
            currentPointer = list_begin;
    
            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->list0;
    }
    


  • Schau mal selber.
    Deine Deklaration (der Prototyp)

    int insert(struct element, struct element);
    

    und deine Definition:

    int insert(struct element *list_begin,struct element *currentPointer)
    { ....
    

    Das passt nicht.



  • Ok, ich habe jetzt die Funktionsdefinition wie folgt geändert:

    int insert(struct element*, struct element*);
    

    Außerdem habe ich noch den Funktionsaufruf so geändert:

    insert(list_begin,currentPointer);
    

    Jetzt werden zwar keine Fehler mehr angezeigt, aber auch anscheinend kein Wert richtig eingetragen, d.h. ich kann zwar nach einem Teilstring suchen, es wird aber kein Treffer angezeigt und auch sonst die Liste nicht ausgegeben, deswegen habe ich den Funktionsaufruf angepasst, weil die Zeiger ja auf list0 zeigen sollen:

    insert(list_begin->list0,currentPointer->list0);
    

    Jetzt wird alles richtig compiliert, ich bekomme aber einen Speicherzugriffsfehler, woran könnte das liegen?
    Achja, ich habe, der Einfachheit halber, alle Variablen global definiert, was an für sich ja nicht so gut ist. Könnten deshalb nicht auch Fehler auftreten?



  • Überleg mal, welche Werte die Paramter beim ersten Aufruf haben.
    Sonst nimm den Debugger.

    Oder gib mal die Werte von deinen Zeigern in main und in insert aus.zur Kontrolle auf dem Bildschirm aus. Für Zeiger gibt es bei printf den Formatspecifier %p

    rei0d schrieb:

    Jetzt wird alles richtig compiliert, ..

    Dann schalte mal den Warnlevel auf Maximum.

    list_begin->list0 ist ein char*
    insert ewartet doch aber ein struct element*

    rei0d schrieb:

    Achja, ich habe, der Einfachheit halber, alle Variablen global definiert, was an für sich ja nicht so gut ist.

    Das macht es nicht einfacher, sondern nicht lesbar/nachvollziehbar.



  • Beim ersten Aufruf waren beide NULL bzw nil. Eigentlich muss ich currentPointer ja auch gar nicht übergeben, da ihm sowieso list_begin zugeordnet wird, deshalb habe ich mir gedacht, dass es sinnvoller ist, tmpPointer, also den Zeiger auf das Element, das eingefügt werden soll, zu übergeben.
    Ich habe jetzt noch ein paar Kleinigkeiten geändert und u.a. auch die Variablen wieder global in der main() deklariert.
    Mein jetziges Problem ist, dass er für list_begin immer wieder den NULL-Zeiger hat, obwohl in der sort()-Funktion ein Zeiger übergeben wird, der nicht NULL ist, was ich auch mit printf("%p",list_begin); immer ab prüfe.
    Meine Vermutung ist, dass der Rückgabetyp nicht char oder struct element* sein sollte, mir fällt aber partout nicht ein, was er sonst ist.

    #include <stdio.h>
    #include <stdlib.h>
    #define MaxCharPerLine 51
    
    struct element
    {
        char *list0;
        struct element *next;
    };
    
    char sort(struct element*, struct element*);
    
    int main ()
    {
    
        /* Zeiger auf Anfang der Liste */
        struct element *list_begin = NULL;
    
        /* Temporaerer Zeiger auf Listenknoten */
        struct element *tmpPointer;
        /* Zeiger auf aktuelles Element */
        struct element *currentPointer;
        /* Zeifer auf vorheriges Element */
        struct element *beforePointer;
    
        char t[MaxCharPerLine];
    
        int tlen = 0;
        int cnt = 0;
        char s[MaxCharPerLine];
        char search[MaxCharPerLine];
        int found = 0;
        int number = 0;
        int repeat = 1;
    
        /* Einlesen in list0 */
        while(fgets(t, sizeof(t), stdin)!=NULL)
        {
            tlen = strlen(t);
            if(tlen == 1)
            {
                free(s);
                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);
            sort(list_begin,tmpPointer);
        }
    
        /* Ausgabe von list0 */
        tmpPointer = list_begin;
    
        while (tmpPointer != NULL)
        {
    
            printf ("%s\n", tmpPointer -> list0);
    
            /* Zeiger auf nächsten Eintrag */
            tmpPointer = tmpPointer -> next;
    
        }
    
        /* Freigeben von stdin, sodass Eingabe über Tastatur erfolgen kann */
        freopen("/dev/tty","r",stdin);
    
        /* Suche nach Teilkette */
        while(repeat)
        {
            printf("Gesuchte Zeichenkette: ");
            scanf("%s",&search);
            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)
                {
                    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;
        }
    
        free(tmpPointer);
    
        return 0;
    
    }
    char 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;
            }
        }
    
        printf("%p\n",list_begin);
        return list_begin;
    
    }
    


  • 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