Supportnet Computer
Planet of Tech

Supportnet / Forum / Anwendungen(Java,C++...)

Liste speichern in C und wieder laden





Frage

Hi Leute, ich bin gerade dabei die Programmiersprache C zu lernen. Dabei bin ich jetzt auf ein Problem gestoßen, das ich bisher noch nicht lösen konnte. Und zwar habe ich eine Programm mit einer einfach verketten Liste und möchte diese auf einem Datenträger speichern. Das Problem, das ich damit habe ist, das die Liste sich aus structs zusammen setzt und das die Liste dynamisch ist. Mein Versuch mit fread/fwrite hat nicht so ganz funktioniert, den bei fread musste ich eine Größe der einzulesenden Structs eingeben, nur leider kenne ich diese ja nicht, da die Liste dynamisch ist. Wie lösen die Profis das Problem ??? Ich bin für jeden Tipp dankbar...

Antwort 1 von Pumuckel

Leicht abgeänderter Auszug aus der MSDN-Library zu "fscanf":


#include <stdio.h>

FILE *stream;

void main( void )
{
   long l;
   float fp;
   char *s;
   char c;
   s=new char[]; //allocate memory for string

   stream = fopen( "fscanf.out", "w+" );

   if( stream == NULL )
      printf( "The file fscanf.out was not opened\n" );
   else
   {
      fprintf( stream, "%s\n", "string");
      fprintf( stream, "%ld\n", 65000);
	  fprintf( stream, "%f\n", 3.1416);
	  fprintf( stream, "%c\n", 'a');
	     
      /* Set pointer to beginning of file: */
      fseek( stream, 0L, SEEK_SET );

      /* Read data back from file: */
      fscanf( stream, "%s\n", s ); //read string
      fscanf( stream, "%ld\n", &l ); //read long	
      fscanf( stream, "%f\n", &fp ); //read float
      fscanf( stream, "%c\n", &c ); //read character	

      /* Output data read: */
      printf( "%s\n", s );
      printf( "%ld\n", l );
      printf( "%f\n", fp );
      printf( "%c\n", c );

      fclose( stream );
   }
}


Die Datentypen entsprechend Deiner Liste anpassen (Pointer auf Struct-> Structkomponente).
Für eine Schleife zum Auslesen der Liste mußt Du noch eine EndOfFile-Prüfung schreiben.

Antwort 2 von semi

So kannst Du Strukturen in Datei speichern.

#include <stdio.h>

struct Datensatz {
  int id;
  char name[64];
  ... usw.  
};

int main() {

  struct Datensatz rec;
  FILE *datfile;

  memset((void*)&rec,0,sizeof(rec));  // mit 0 füllen

  datfile = fopen("daten.dat","wb");

  //... Weitere Verarbeitung

  fwrite(&rec,sizeof(rec),1,datfile);
  fclose(datfile);

} 
Genau so machst Du es mit jedem Element der Liste.

Gruß,
Michael

Antwort 3 von FrankieH

die beiden Lösungen sind beide nicht das, was der Fragesteller braucht. Der Beispielcode von fscanf hat das Thema sogar völlig verfehlt.

Er spricht von einer verketteten Liste - dynamisch! Diese wird in einer struct gespeichert - logisch.

Also sieht die struct z.B. so aus, wobei ich Semis Vorlage verwende:


struct Datensatz {
    struct Datensatz *next;
    int id;
    char name[64];
    //  ... usw.  
};

Nun wäre Semis Lösung fast ok - aber: In der Datei stehen Pointer. Wäre schon Zufall, wenn diese Pointer wieder treffen. Um es einfach zu handhaben, könnte man sie herauschreiben wie Semi es gemacht hat, muss aber beim Einlesen die Pointer neu aufbauen.

Jetzt kommt aber das nächste Problem, denn oftmals (eigentlich sogar idR) enthalten solche Listen wiederum Pointer. Zum Beispiel:


struct Datensatz {
    struct Datensatz *next;
    int id;
    char *name;
    //  ... usw.  
};

Und schon fällt auch Semis Lösung auf die Nase.

Jetzt frage ich mich natürlich, warum ein Programmieranfänger sich direkt mit solchen Problemen beschäftigt - nicht dass ich deswegen das nicht achte, aber besser wäre es schon, sich erst einmal allgemein mit Datentypen, Pointern, und IO-Operationen auseinanderzusetzen.

Also Klaus Dieter - je nachdem wie Deine struct aufgebaut ist, musst Du die struct-Elemente einzeln herauschreiben oder kannst Semis Lösung zum herausschreiben verwenden. Beim Einlesen musst die Verkettung wieder aufbauen - also Datensatz für Datensatz einlesen und mit append ans Ende der Liste hängen.

Nette Aufgabe - nur Mut.
Frankie




Antwort 4 von semi

@FrankieH
Klar. War nur ein Beispiel, wie man eine Struktur in Datei schreibt.

@klaus
Am besten mach es so, dass die eigentliche Liste getrennt verwaltet wird.
z.B.

struct Record {
  int id;
  char name[64];
  ...usw.
};

struct ListNode {
  struct ListNode *next = NULL;
  struct ListNode *prev = NULL;
  struct Record *data = NULL;
};

struct List {
  struct ListNode *first = NULL;
  struct ListNode *last = NULL;
  int size = 0;
};
In diesem Fall kannst Du die Liste durchgehen und solange next nicht NULL ist data in die Datei schreiben bzw. rückwärts lesen und die Liste aufbauen. Das ganze am besten noch als ein Template, so dass es sich auf beliebige Strukturen anwenden läßt. (void * für die Daten könnte auch hinhauen)

Gruß,
Michael

Ich möchte kostenlos eine Frage an die Mitglieder stellen:


Ähnliche Themen:


Suche in allen vorhandenen Beiträgen: