[c] Liste, Pointer, Zugriff späterer Programmverlauf?

  • Themenstarter Themenstarter Mavinas
  • Beginndatum Beginndatum
M

Mavinas

Hi,

habe schon wieder eine Frage...

Und zwar lese ich eine Datei zeilenweise aus.
Bestimmte Dinge werden dabei von mir mit Hilfe von strtok getrennt und anschließend in einer linearen Liste abgelegt.

Soweit so gut.

Nun möchte ich allerdings auf die Daten im späteren Programmverlauf in einer anderen Funktion wieder zugreifen.

Ich denke man muss ständig die Zeiger übergeben, aber ich habe leider keine Ahnung wie.


Meine Liste ist beispielhaft so aufgebaut:
C++:
struct liste
{
     int zahl1;
     char wert1;
     struct liste *next;
}

struct liste *root=NULL;

In der Funktion wird ein weiterer Zeiger initialisiert, der mir die augenblickliche Position zurückgibt.

C++:
 struct liste *pos;

Also "root" benutze ich für den Anfang, fürs erste Element der Liste und "pos" für jedes weitere. "next" gibt mir das Ende der Liste an.


Wie komme ich also in einer anderen Funktion an die eingelesenen Daten ran?


Grüße
 
Hi

Also "root" benutze ich für den Anfang, fürs erste Element der Liste und "pos" für jedes weitere. "next" gibt mir das Ende der Liste an.

Zeig mal etwas mehr.
Ich hab den Verdacht, dass du da etwas gründlich missverstanden hast.
next sollte jeweils auf das Nächste zeigen...

Damit du Zugriff auf die Liste hast sollte Root schon reichen
 
Zuletzt bearbeitet:
Die Funktion sieht in etwas so aus:
Die Liste befindet sich in einer seperaten Header Datei.

C++:
struct liste
{
     int zahl1;
     char wert1;
     struct liste *next;
}
 
struct liste *root=NULL;

C++:
struct liste *pos; 
FILE *data=NULL;                     
char buf[100];                      
char del[]=" \n";                  
char *temp;

//vorher wird die Datei noch geöffnet. Den Teil habe ich weggelassen. 
//Ich beschränke mich nur auf das Einlesen und Ablegen in der Liste
while(fgets(buf, 100, data))
            {
                    if(root==NULL)
                    {
                        if((root=malloc(sizeof(struct liste)))==NULL)
                        {
                            printf("kein Speicher\n");
                            return 1;
                        }
                        temp=strtok(buf, del);
                        root->zahl1=atoi(temp);
                        temp=strtok(NULL, del);
                        root->wert1=*temp;
                        root->next=NULL;

                    else
                    {
                        pos=root;
                        while(pos->next!=NULL)
                            pos=pos->next;

                        if((pos->next=malloc(sizeof(struct liste)))==NULL)
                        {
                            printf("kein Speicher\n");
                            return 1;
                        }
                        pos=pos->next;
                        temp=strtok(buf, del);
                        pos->zahl1=atoi(temp);
                        temp=strtok(NULL, del);
                        pos->wert1=*temp;
                        pos->next=NULL;
                    }
fclose(data);

Die Funktion bekommt derzeit nichts übergeben.
 
Zuletzt bearbeitet von einem Moderator:
1) Globale Variablen...wenn, dann nicht in Headerdateien.
Sobald du das Programm in mehrere Codedateien aufteilst bekommst du damit Linkerfehler.
Definier root im main.

2) pos als Hilfsvariable ist OK

3) Um root aus dem main in die Funktion zu übergeben gibt es zwei Möglichkeiten.
Wenn du nicht nur C, sondern auch die mit C++ neu dazugekommenen Sachen verwenden darfst/kannst/willst, schreibst du "struct liste *&root" und übergibst beim Aufruf einfach "root".
Andernfalls "struct liste **root" und "&root", für die Möglichkeit musst du aber auch den Zugriff in der Funktion an jeder Stelle umändern. Variante 1 ist bequemer.

4) Hab mir den Einfügeprozess nicht genau angeschaut, aber du soltlest sowas wie "Einfügen in Liste", "Löschen aus Liste" etc. in eigene Funktionen packen.
In dieser besprochenen Funktion dann nur den Dateiteil übernehmen und immer die andere Einfügefunktion aufrufen.
Einfüge in die Liste wirst du sicher noch an anderen Stellen; wäre doch sinnlos immer neu programmieren.

Gruß
 
Jo, danke dir.
Das mit "root" probiere ich im Laufe des Tages nochmal.

Das Einfügen ist leider in Wirklichkeit etwas komplizierter. Habe mich hier wirklich auf das Wesentliche beschränkt. Ansonsten ist es natürlich besser, wenn man dafür eine extra Funktion schreiben würde, die gegebenenfalls an anderer Stelle wieder verwendet werden kann.

Die Liste in einer Headerdatei abzuspeichern ist aber so Programmierstil technisch ok?

Edit:
Kleine Frage noch.
Die Funktion müsste den Zeiger am Ende auch wieder zurückgeben, oder?
Wie mache ich das dann mit den Fehlermeldungen "return 1" etc. die auftreten können?
Ich bin grad auf dem Stand, dass man nur eine Sache zurückgeben kann.
 
Die Liste in einer Headerdatei abzuspeichern ist aber so Programmierstil technisch ok?
Was ist "die Liste"?
Das root nicht da rein gehört, sagte ich schon.
Zu den Funktionen drin: Die sollten in ine dazugehörende cpp-Datei.
In der Heaserdatei nur Returntyp, Funktionsname, Parameter und einen Striichpunkt übriglassen.

zB.
In der .h
C++:
void funk(int i);
in der .cpp
C++:
void funk(int i)
{
    printf("%d\n", i);
}

Ich bin grad auf dem Stand, dass man nur eine Sache zurückgeben kann.
Ja, stimmt.
Die Funktion müsste den Zeiger am Ende auch wieder zurückgeben, oder?
Bei den zwei Übergabemöglichkeiten, die ich geschrieben habe, ist das nicht nötig.
Da werden Änderungen automatisch ins main (oder wo die Funktion sonst aufgerufen wird) übernommen.
Du kannst die Returnwerte also weiterhin für Fehlerwerte nutzen

Gruß
 
Was ist "die Liste"?

Also im Moment steht folgendes in der Header:

C++:
#ifndef LIST_H_
#define LIST_H_

//Include Dateien
//[...]

struct liste
{
     int zahl1;
     char wert1;
     struct liste *next;
}

struct liste *root=NULL;

//Funktionsprototypen
int lade_daten();

#endif /* LIST_H_ */

"root" ändere ich dann noch.
 
Zuletzt bearbeitet von einem Moderator:
Ich habe das mit "root" jetzt so probiert wie du beschrieben hast.

C++:
//In Main
struct liste **root=NULL;

//Übergabe an erste Funktion
function1(&root);
         //Direkte Weitergabe an untergeordnete Einlesefunktion
              function2(&root);

Nun hat sich allerdings ein weiteres Problem eingeschlichen.
In meiner einlese Funktion erkennt der Compiler die einzelnen Variablen der Liste nicht mehr.

Heisst ich kann nicht wie zuvor mit "root->zahl1" etwas zuweisen.

C++:
error: request for member 'zahl1' in something not a structure or union


Edit:
Habs schon selbst rausgefunden.
Muss die Liste auch mit übergeben.
Also bei der Fnktionsdefinition "struct liste *" schreiben.

Danke nochmal!

Edit2:
Wenn ich im weiteren Programmverlauf auf "root" zugreifen will, stürzt es ab.
Ich kann also immernoch nur innerhalb der einlese Funktion ohne Probleme darauf zugreifen.
Irgendwas ist noch falsch. Ich such mal weiter.
 
Zuletzt bearbeitet von einem Moderator:
Hi

Im main nur mit einem * wie du es bis jetzt ja gehabt hast!

Das *& oder ** meinte ich bei der Funktionsdefinition, zB.
C++:
int funktion(struct liste *&root)

Und ich empfehle nocheinmal die *&-Variante.
Sonst wirds in der Funktion umständlich.
 
Zurück