Probleme mit Zeigern in Funktion



  • gibt es da den eine Möglichkeit?

    Nochmal zum Verständnis ich möchte buch, verlag und Autor(sind alles Array von Struct) nicht Global deklarieren. Habe es in der Main-Fkt deklariert.

    Jetzt möchte ich sie der Fkt. file bekannt machen und die da auch verändern können. Da gibt es doch eine Variante mit Zeigern, leider weiß ich nicht wie.

    Könnt ihr mir helfen?

    Danke

    Benno



  • benno87 schrieb:

    Habe es in der Main-Fkt deklariert.

    Wie denn?

    Eigentlich sollte void file(TBuch buch[], oder void file(TBuch *buch, reichen (ist das gleiche).



  • benno87 schrieb:

    Nochmal zum Verständnis ich möchte buch, verlag und Autor(sind alles Array von Struct) nicht Global deklarieren. Habe es in der Main-Fkt deklariert.

    Ja, super erkannt.
    Globale Variablen sind meistens Unsinn.

    benno87 schrieb:

    Jetzt möchte ich sie der Fkt. file bekannt machen und die da auch verändern können. Da gibt es doch eine Variante mit Zeigern, leider weiß ich nicht wie.

    Indem du einen Zeiger auf das was du in der Funktion ändern willst, übergibst, also in deinem Fall einen Zeiger auf dein struct-Array.



  • da ich einfach nicht weiter komme hier nochmal alles was ich programmiert habe.
    Wie muss ich ich die Zeiger setzen damit ich die oben beschriebene Funktionalität erreiche

    danke nochmal

    main.c

    #include "buecher_func.h"
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        //Variablen dek
        TBuch *buch[1000];
        TVerlag *verlag[100];
        TAutor *autor[300];
        int lautor = 0;
        int lverlag = 0;
    
        // Bücher aus Datei lesen und in Struktur Buch speichern
        file(&buch,&autor,&verlag, &lautor, &lverlag);
       return 0;
    }
    

    buecher_func.h

    ifndef BUECHER_FUNC_H_INCLUDED
    #define BUECHER_FUNC_H_INCLUDED
    
    enum{MAXL = 250};
    char line[MAXL];
    
    //Datentypdefinition
    
    typedef struct{
        char *title;
        char *autor;
        char *verlag;
        char *jahr;
        char *isbn;
    }TBuch;
    
    typedef struct{
        char *name;
    }TAutor;
    
    typedef struct{
        char *name;
    }TVerlag;
    
    //Funktiondeklaration
    void file(TBuch* buch, TAutor* autor, TVerlag* verlag, int* lautor, int* lverlag);
    char* noredu(char* ptr, char* feld[], char* buch[], int *last);
    
    #endif
    

    buecher_func.c

    void file(TBuch* buch, TAutor* autor, TVerlag* verlag, int* lautor, int* lverlag)
    {
        FILE *fp; //Zeiger für Datei
        char *ptr;
        int i=1;
    
        //Öffnen der Datei
        if((fp=fopen("/media/3AF25DA0244915B2/Eigene Dateien/studium/Informatik/Inf2/buecher_proj/buecherliste.csv","r") )== NULL)
        {
            fprintf(stderr,"*** Error: Can't open 'Datenname' for read!\n");
        }
    
        //Durchlaufen der geöffneten Datei und speichern in Struktur Buch
         while (fgets(line, 1000, fp) != NULL)
        {
            *(buch[i]->title) = strtok(line,";");
            *(buch[i]->autor) = strtok(NULL,";");
            //ptr=strtok(NULL,";");
            //(*buch[i]->autor) = noredu(ptr,(&autor)->name,&buch->autor, lautor);
            (*buch[i]->verlag) = strtok(NULL,";");
            //ptr = strtok(NULL,";");
            //(*buch[i]->verlag) = noredu(ptr,&verlag->name,&buch->verlag, lverlag);
    
            (*buch[i]->jahr) = strtok(NULL,";");
            (*buch[i]->isbn) = strtok(NULL,";");
            i++;
        }
        // Datei schließen
        fclose(fp);
    }
    
    char* noredu(char *ptr ,char* feld[] ,char* buch[], int* last)
    {
        int j=0;
        //Vergleich ob Autor schon vorhanden
        for(j=0;j<(*last);j++)
        {
            if(strcmp(ptr,buch[j])==0)
                return &buch[j];
        }
        last++;
        // Anlegen eines neuen Autors
        feld[(*last)] = ptr;
        return &feld[(*last)];
        //printf("%s \n",*buch[i].autor);
    
    }
    


  • Wie schon gesagt, ist TBuch *buch[1000]; ein Array mit 1000 Zeigern auf TBuch. Damit hast du noch kein Speicherplatz für dein TBuch.

    Genau so sieht es mit title, jahr, verlag aus. Das sind alles Zeiger die auf keinen gültigen Speicherplatz zeigen.

    Du kannst den Speicherplatz dynamisch mit malloc anfordern.

    file ist kein guter Funktionsname.

    strtok() verändert das line und es wird jedesmal überschrieben.
    Dadurch hast du eigentlich nur die Werte von deiner zuletzt gelesenen Zeile.

    Für dich sollte es erstmal einfacher sein, du machst das ganze mit Arrays.



  • DirkB schrieb:

    Wie schon gesagt, ist TBuch *buch[1000]; ein Array mit 1000 Zeigern auf TBuch. Damit hast du noch kein Speicherplatz für dein TBuch.

    hab ich jetzt so

    TBuch buch[1000];
    TVerlag verlag[100];
    TAutor autor[300];
    

    Du kannst den Speicherplatz dynamisch mit malloc anfordern.

    brauch ich das gerade?

    file ist kein guter Funktionsname.

    Ich weis mir ist nix besseres eingefallen

    strtok() verändert das line und es wird jedesmal überschrieben.
    Dadurch hast du eigentlich nur die Werte von deiner zuletzt gelesenen Zeile.

    ich hatte es erst mit globalen Variablen da hat es mit dieser Variante beklappt

    Für dich sollte es erstmal einfacher sein, du machst das ganze mit Arrays.

    Ist Teil einer Aufgabe und muss so bleiben

    typedef struct{
        char *title;
        char *autor;
        char *verlag;
        char *jahr;
        char *isbn;
    }TBuch;
    
    typedef struct{
        char *name;
    }TAutor;
    
    typedef struct{
        char *name;
    }TVerlag;
    


  • benno87 schrieb:

    Ist Teil einer Aufgabe und muss so bleiben

    Dann brauchst du malloc.

    benno87 schrieb:

    ich hatte es erst mit globalen Variablen da hat es mit dieser Variante beklappt

    Das kannst du machen, wenn du für jedes Buch eine eigene Zeile hast. Besser ist es aber, du kopierts die Strings in den mit malloc besorgten Speicher.

    Wer hat sich die TBuch-Struct eigentlich ausgedacht? Oder ist das "title" ein Tippfehler von dir.



  • Dann brauchst du malloc.

    gibt es nicht so möglichkeiten wie

    char *x
    x ='Hallo Welt!'
    printf("%s \n",x)
    

    Wer hat sich die TBuch-Struct eigentlich ausgedacht? Oder ist das "title" ein Tippfehler von dir.

    ja ist ein Tippfehler von mir!

    Ich bin zwischen soweit das er es mir innerhalb der Fkt. richtig ausgibt, aber in der Main Fkt. nicht.



  • benno87 schrieb:

    gibt es nicht so möglichkeiten wie

    char *x
    x ='Hallo Welt!'
    printf("%s \n",x)
    

    Wenn die Syntax stimmt, geht das.
    Aber das hilft dir nicht weiter.
    Das "Hallo Welt!" ist ein Stringliteral und der Speicherplatz dafür wird vom Compiler reerviert. Nebenbei kannst du die auch nicht ändern (beschreiben).

    Und wegen int i=1; : Arrays fangen in C bei 0 an. Immer.



  • benno87 schrieb:

    #include "buecher_func.h"
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        //Variablen dek
        TBuch *buch[1000];
        TVerlag *verlag[100];
        TAutor *autor[300];
        int lautor = 0;
        int lverlag = 0;
    
        // Bücher aus Datei lesen und in Struktur Buch speichern
        file(&buch,&autor,&verlag, &lautor, &lverlag);
       return 0;
    }
    

    Das Design sieht ja prinzipiell schon mal gut aus, wenn auch falsch.
    Du hast deine Arrays schon definiert, d.h. die ändern sich selbst nicht mehr, nur noch der Inhalt. Einzig die Anzahl der (gültigen) Arrayeinträge wird sich ändern, deshalb musst du auch nur hierfür Zeiger übergeben, also in etwa:

    int main()
    {
        /*Variablen Definition */
        TBuch buch[1000];
        TVerlag verlag[100];
        TAutor autor[300];
        int lbuch = 0;
        int lautor = 0;
        int lverlag = 0;
    
        // Bücher aus Datei lesen und in Struktur Buch speichern
        file(buch,autor,verlag,&lbuch,&lautor,&lverlag);
        return 0;
    }
    

    Jetzt dürfte es für dich auch nicht mehr so schwierig werden, da eine Dimension wegfällt.
    Trotzdem musst du aber noch statt wie bisher nur die Zeiger aus der Leseschleife abzuspeichern, neuen Speicher für die Strings belegen und dann die Zeiger darauf in deinen Arrays abspeichern, also jeweils noch malloc/strcpy.


Anmelden zum Antworten