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[],
odervoid 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 erreichedanke 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 dasline
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 dasline
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.