Forum: PC-Programmierung Doppeltverkettete Liste Speichern Datei


von Peter S. (ungoliant)


Lesenswert?

HuHu

stecke grad ziemlich fest. ziel ist es eine doppelt verkettete 
zeigerliste in einer datei ab zu speichern und nacher wieder zu öffnen.

ein problem das ich mir vorstelle ist, dass man bei den zeigern in der 
liste ja grade adressen speichert, die nach einem neustart ja ganz 
anders belegt sind.

habe schon viel gesucht und nirgends was gefunden.....

das ganze soll in c laufen...

wäre super wenn mich jmd in die richtige richtung schubsen könnt :)

danke schonmal im voraus~

von Karl H. (kbuchegg)


Lesenswert?

Peter Schol schrieb:

> ein problem das ich mir vorstelle ist, dass man bei den zeigern in der
> liste ja grade adressen speichert, die nach einem neustart ja ganz
> anders belegt sind.

genau so ist es auch

> wäre super wenn mich jmd in die richtige richtung schubsen könnt :)

Du speicherst keine Zeiger in der Datei.

Du schreibst deine Liste, Element für Element in die Datei.

Beim Wiedereinlesen holst du 1 ELement nach dem anderen aus der Datei 
und lässt es von deinem Einfügecode an die Liste hinten anhängen. Du 
tust also so, als ob dein Benutzer die Liste ganz von vorne, beginnend 
mit einer leeren Liste neu aufbauen würde. Nur dass du keinen Benutzer 
hast, sondern die einzufügenden Werte von einer Datei kommen.

: Bearbeitet durch User
von Udo S. (urschmitt)


Lesenswert?

Karl Heinz hat fast alles gesagt. Nur eins noch:
Wenn du in der Datei (oder einer anderen Datei) noch Informationen 
ablegen musst die zu bestimmten Elementen in der Liste verweisen, und 
die im Speicher eben ein Zeiger auf ein Element der Liste waren, dann 
musst du jedem Element der Liste eine ID zuordnen, die du dann als 
Referenz benutzt.
Wenn die Liste dann im Speicher wieder aufgebaut wird, kannst du über 
die ID das/die richtige(n) Element(e) suchen und deine Zeiger wieder 
direkt auf die Adressen der Elemente zeigen lassen.
Die einfachste ID ist einfach die Durchnumerierung der Elemente der 
Liste (Schreibreihenfolge).

: Bearbeitet durch User
von Peter S. (ungoliant)


Lesenswert?

vielen dank für eure antworten.

genau den schubs hab ich gebraucht

liebe grüße

von Peter S. (ungoliant)


Lesenswert?

nun weiss ich nicht, wie ich aus der datei die daten an die richtige 
stelle in meiner liste schreiben soll Oo

also liegen sie in der gleichen reihenfolge auf der datei ?

irgendwie muss ich ja den ersten datensatz (ist ein int names "nr" bei 
mir)
in meiner liste unter neu->nr; unterkriegen und danach den zweiten 
datensatz (titel bei mir) in meiner liste unter neu->titel auf dem 
gleichen element unterkriegen.

bin auch leider hier wieder etwas ratlos..... die daten liegen doch 
einfach "nebeneinander" in der reihenfolge auf der datei, wie ich sie 
eingegeben habe , oder ?

vielen dank schonmal

von npn (Gast)


Lesenswert?

Peter Schol schrieb:
> nun weiss ich nicht, wie ich aus der datei die daten an die richtige
> stelle in meiner liste schreiben soll Oo

Wenn du die Datei öffnest, schreibst du die gelesenen Datensätze nicht 
an "eine bestimmte Stelle der Liste". Du erstellst du dir beim Öffnen 
des Files eine neue Liste und machst dann das gleiche, als wenn ein 
Benutzer einen neuen Datensatz (oder eben mehrere nacheinander) eingibt.

von Peter S. (ungoliant)


Lesenswert?

wenn ein benutzer eine list erstellt, gebe ich nr den wert 1 und zähle 
automatisch hoch, zuerst wird der bennutzer aufgefordert einen titel ein 
zu geben, danach einen interpreten, dann hüpft die liste einen weiter 
und der benutzer soll einen titel eingeben.

hab kA wie ich das aus der datei auslesen kann, ich weiss ja garnicht wo 
ich auf der datei meine titel habe oder meinen interpreten.

von npn (Gast)


Lesenswert?

Peter Schol schrieb:
> hab kA wie ich das aus der datei auslesen kann, ich weiss ja garnicht wo
> ich auf der datei meine titel habe oder meinen interpreten.

Ich ging davon aus, daß du eine Datei einlesen möchtest, die du vorher 
selbst auf die Platte geschrieben hast. In diesem Falle müßtest du ja 
wissen, welche Information wo gespeichert ist, denn du hast es ja selbst 
getan. Oder zumindest die Routine geschrieben, die es tut.
Wenn du aber eine "unbekannte" Datei einlesen möchtest, dann weiß ich 
das Format natürlich auch nicht...

von Thorsten H. (lordvader91)


Lesenswert?

Dann musst du dir mal Gedanken über eine Datenstruktur machen, wie deine 
Nr und die dazugehörigen Informationen dort abgelegt werden.
Schau dir mal XML oder JSON an. Kannst du mal als grobe Anregung nutzen.
Wenn du einen Paser für die beiden Formate hast, dann kannst du den 
nutzen, ansonsten musst du dir halt selbst etwas überlegen.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Ich würde Dir auch dringend zu einem XML-basierten Datenformat raten. 
Dann ist es nämlich möglich, die Dateien auch mit einem Texteditor o.ä. 
auf Plausibilität zu prüfen. Es gibt auch spezielle XML-Editoren, die 
selbst auch Prüfungen der Syntax und Semantik durchführen können.

Das direkte Speichern des Inhaltes von "structs" o.ä. ist in den meisten 
Fällen die schlechteste Variante, wenn man nämlich nicht sehr genaue 
Überlegungen anstellt, welche Auswirkungen das haben kann, z.B. beim 
Wechsel des Compilers oder irgendwelche Änderungen der Datenausrichtung 
bzw. des Paddings.

Ach so, noch ein Hinweis: Es empfiehlt sich dringend, als erstes 
Datenelement in einer Datei eine Formatkennzeichnung unterzubringen. 
Ändert man nämlich später das Datenformat, muss die Leseroutine ggf. in 
der Lage sein, altes und neues Format zu unterscheiden. Daher sollte die 
Formatkennzeichnung auch immer am Anfang der Datei stehen und nicht 
weiter hinten.

: Bearbeitet durch User
von Udo S. (urschmitt)


Lesenswert?

Peter Schol schrieb:
> in meiner liste unter neu->nr; unterkriegen und danach den zweiten
> datensatz (titel bei mir) in meiner liste unter neu->titel auf dem
> gleichen element unterkriegen.

Wenn ich das so lese, dann speicherst du nicht einen einfachen String in 
der Liste sondern eine Struktur.
Also überlege dir erst wie du die gesamte Struktur speichern und wieder 
korrekt lesen kannst.
Wenn du dafür eigene Funktionen hast kannst du anfangen dir zu überlegen 
wie du die Liste dieser Strukturen speicherst.

Ja man kann sowas als XML ablegen, aber wenn ich die Beiträge von Peter 
Schol lese ist das noch um Faktor 10 zu schwer. Dann erst mal ein 
eigenes einfaches proprietäres Format.

von Peter S. (ungoliant)


Lesenswert?

also ich erstelle die datei schon selber. ich würde nur den interpreten 
und den titel, also 2 arrays in der datei abspeichern. leider weiss ich 
trotzdem nicht, wie ich die einzelnen wörter aus der datei in die 
einzelnen arrays schreiben kann -.-

von Klaus W. (mfgkw)


Lesenswert?

C-Buch?

von Udo S. (urschmitt)


Lesenswert?

Peter Schol schrieb:
> den interpreten und den titel, also 2 arrays

Falscher Ansatz, Daten die zusammengehören auch zusammen speichern, 
nämlich in einer Struktur.
struct -> C Buch

von Thorsten H. (lordvader91)


Lesenswert?

Ganz einfach geht es auch mittels CSV-Datei. Könnte beispielsweise dann 
so aussehen:
1
Interpret1;Titel1
2
Interpret2;Titel2
3
...

Dann musst du eben jede Zeile auslesen und den Inhalt der Spalten deinen 
Strukturelementen zuweisen.
Deine Struktur benötigt dann die Elemente Interpret und Titel und 
die Liste muss als Daten die Strukturen enthalten.

von Karl H. (kbuchegg)


Lesenswert?

Peter Schol schrieb:
> wenn ein benutzer eine list erstellt, gebe ich nr den wert 1 und zähle
> automatisch hoch, zuerst wird der bennutzer aufgefordert einen titel ein
> zu geben, danach einen interpreten, dann hüpft die liste einen weiter

was n das für eine Liste?

Vielleicht solltest du dir erst mal deine Listenfunktionen so zurecht 
legen, dass du leicht benutzbare Basisfunktionen hast? Das klingt mir 
stark danach, als ob du da einfach wild drauflosprogrammiert hast ohne 
dir irgendwelche Gedanken zur MOdularisierung gemacht zu haben.

von Karl H. (kbuchegg)


Lesenswert?

Peter Schol schrieb:
> also ich erstelle die datei schon selber. ich würde nur den interpreten
> und den titel, also 2 arrays in der datei abspeichern. leider weiss ich
> trotzdem nicht, wie ich die einzelnen wörter aus der datei in die
> einzelnen arrays schreiben kann -.-
1
struct meineDaten
2
{
3
  char  Name[80];
4
  char  Interpret[80];
5
};
6
7
struct meineDatenElement
8
{
9
  struct meineDaten         daten;
10
  struct meineDatenElement* previous;
11
  struct meineDatenElement* next;
12
};
13
14
struct meineDatenElement* theListRoot = NULL;
15
16
17
void addAtTail( meineDaten* newData )
18
{
19
   .... code der newData in einem meineDatenElement verpackt und
20
   .... beginnend bei 'theListRoot' anhängt
21
}
22
23
void deleteList()
24
{
25
  ... löscht alle Items aus der Liste 'theListRoot'
26
}
27
28
void writeTo( const char* fileName )
29
{
30
  FILE* outFile;
31
32
  outFile = fopen( fileName, "wb" );
33
34
  if( outFile ) {
35
    struct meineDatenElement* item = theListRoot;
36
37
    while( item ) {
38
      fwrite( item.daten, sizeof( item.daten ), 1, outFile );
39
      item = item->next;
40
    }
41
42
    fclose( outFile );
43
  }
44
}
45
46
int readFrom( const char* fileName )
47
{
48
  FILE* inFile;
49
  int   retValue = 0;
50
51
  inFile = fopen( fileName, "rb" );
52
  if( !inFile )
53
    return 1;
54
55
  struct meineDaten readItem;
56
57
  deleteList();
58
  while( fread( &readItem, sizeof( readItem ), 1, inFile ) )
59
    addAtTail( &readItem );
60
61
  if( !feof( inFile ) )
62
    retValue = 2;
63
64
  fclose( inFile );
65
66
  return retValue;
67
}


Ich seh jetzt ehrlich das Problem nicht. fwrite und fread können 
problemlos komplette Strukturen mit allem pi pa po schreiben und lesen.

Alles andere bisher gesagte mit Versionsnummer und dergleichen bleibt 
natürlich trotzdem gültig. Aber wenn du hier schon Probleme hast, dann 
denke ich solltest du erst mal die Finger von XML lassen.

Allenfalls könnte man noch die Dateien als Textfiles aufziehen und jedes 
Listenelement als eine Folge von einzelnen Zeilen in die Datei 
schreiben. fprintf und fscanf (bzw. fgets bei Strings) sind in diesem 
Fall deine Freunde.

Wenn ich es mir so recht überlege, wäre das eventuell gar nicht so 
verkehrt, dann dann kannst du mit einem Texteditor in die erzeugten 
Dateien reinschauen und nachsehen, ob korrekt geschrieben wurde. Und das 
ist gerade für Neulinge in nicht zu unterschätzender Vorteil.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Karl Heinz schrieb:
> Ich seh jetzt ehrlich das Problem nicht. fwrite und fread können
> problemlos komplette Strukturen mit allem pi pa po schreiben und lesen.

das das von dir kommt, wundert mich ein wenig. Ich finde es eine 
schlechte Idee eine Struktur zu schreiben. Was ist wenn sich die 
Struktur später ändert, oder jemand von Hand die Datei editiert?

CSV find ich hier etwas besser.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Karl Heinz schrieb:
>> Ich seh jetzt ehrlich das Problem nicht. fwrite und fread können
>> problemlos komplette Strukturen mit allem pi pa po schreiben und lesen.
>
> das das von dir kommt, wundert mich ein wenig.


Der Grund dafür ist recht einfach.

Eine Code Variante zu finden, die selbst ein Neuling in den Griff 
kriegt.

> schlechte Idee eine Struktur zu schreiben. Was ist wenn sich die
> Struktur später ändert, oder jemand von Hand die Datei editiert?

Versionsnummer am Anfang der Datei
Aber lass ihn erst mal seine ersten Sporen verdienen. So wie sich das 
alles liest, liegt da noch viel mehr im Argen.

Ehrlich gesagt verblüffen mich seine Fragen für jemanden der eine 
doppelt verkette Liste (angeblich) im Griff hat. Dagegen ist das bischen 
File Handling Pipifax.

> CSV find ich hier etwas besser.

Fast alles ist besser. Aber auch mehr Aufwand. Und man muss schon mehr 
können.

: Bearbeitet durch User
von Peter S. (ungoliant)


Lesenswert?

vielen dank euch allen für eure vorschläge.

hatte von anfang an schon ein struct als ne doppelt verkettete zeiger 
liste im sinn... @Udo

hab dann aber doch nen struct ohne zeiger und quasi als array struct 
element musik[100] ... also doch bisserl zeigerlike :o gebastelt.

ich weiss kein eleganter weg... aber ich musste es schnell fertig 
bekommen, war ne art hausaufgabe.
für die die es interessiert, hab fprinf und fscanf genommen, was einiges 
an nerven gekostet hat, da ich die strings nicht aus der datei auslesen 
konnte, bis ich ein leerzeichen manuel beim speichern eingefügt hab 
zwischen jedem element.

glaub euch würden die haare ausfallen wenn ich den quellcode sehen 
würdet :p ca 130 zeilen text für bisserl einfügen, löschen, bearbeiten, 
suchen, speichern und laden xD

aber klappt! danke nochmal


>Karl Heinz schrieb:

> Ehrlich gesagt verblüffen mich seine Fragen für jemanden der eine
> doppelt verkette Liste (angeblich) im Griff hat. Dagegen ist das bischen
> File Handling Pipifax.

hab doch nie behauptet meine liste im griff zu haben, deswegen hab ich 
ja gefragt.

liebe grüße noch ~

von Karl H. (kbuchegg)


Lesenswert?

Peter Schol schrieb:
> vielen dank euch allen für eure vorschläge.
>
> hatte von anfang an schon ein struct als ne doppelt verkettete zeiger
> liste im sinn... @Udo
>
> hab dann aber doch nen struct ohne zeiger und quasi als array struct
> element musik[100] ...

Ja, was jetzt?

Ist es eine doppelt verkette Liste oder ist es ein Array?

> also doch bisserl zeigerlike :o gebastelt.

Wenn du ein Array hast, dann hast du ein Array und keine Liste. Du 
kannst nicht einfach neue Bezeichnungen erfinden. Sonst kennt sich 
nämlich kein Schwein mehr aus. Mit Bezeichnungen sind Bedeutungen 
verknüpft. Wenn du sagst 'doppelt verkettete Liste', dann entsteht bei 
deinem Leser eine ganz bestimmte Datenstruktur im Kopf, wenn er über 
dein Problem nachdenkt. Wenn du Array sagst, dann entsteht eine andere 
Datenstruktur.

> ich weiss kein eleganter weg... aber ich musste es schnell fertig
> bekommen, war ne art hausaufgabe.
> für die die es interessiert, hab fprinf und fscanf genommen, was einiges
> an nerven gekostet hat, da ich die strings nicht aus der datei auslesen
> konnte, bis ich ein leerzeichen manuel beim speichern eingefügt hab
> zwischen jedem element.

Tip
Der Zeilenumbruch ist dein Freund und zum Einlesen von Strings nimmt man 
fgets. Denn dann hat man auch keinerlei Probleme mit Leerzeichen in 
einem Namen, was bei Musiktiteln schon mal vorkommen soll.

Und ob in der Datei jetzt steht
1
Dire Straits, Money for nothing
2
Pink Floyd, The Wall
oder ob in der Datei steht
1
Dire Straits
2
Money for Nothing
3
Pink Floyd
4
The Wall
ist Jacke wie Hose.

Der einzige Unterschied ist, dass du beim Rausschreiben einfach nach 
jedem Teil einen zeilenvorschub machst und dass du beim Einlesen mittels 
fgets keine Probleme hast. Du weisst ja, aus wievielen Zeilen ein 
kompletter Eintrag besteht. Hier im Beispiel sind es dann eben 2.

> hab doch nie behauptet meine liste im griff zu haben, deswegen hab ich
> ja gefragt.

Du hast nach File Handling gefragt.
Die Probleme bei dynamischen Datenstrukturen liegen aber ganz woanders. 
Die Operationen 'Einfügen' und ganz besonders 'Löschen' sind schwierig. 
Dass man keinen Pointer bei den Manipulationen verliert, ist schwierig.
Aber wenn natürlich deine doppelt verkette Liste in Wirklichkeit nur ein 
Array ist, dann ist mir alles klar.

Und ich hatte mich schon gefreut, dass endlich mal wer in diesem Forum 
in Richtung dynamische Datenstrukturen geht und es endlich mal 
interessant wird.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.