Linked mit Struktur speichern (OOP)

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Linked mit Struktur speichern (OOP)

Beitrag von Kiffi »

Freizeitcoder hat geschrieben:Für meine zukünftigen Projekte wäre es schon interessant, ob ihre Größe wirklich beschränkt ist.
anscheinend nicht. Habe grade mal testweise eine 9 MB INI-Datei erstellt. Ich nehme an, dass aufgrund der
Plattformunabhängigkeit in PB eine eigene Lösung implementiert worden ist; hier die Win-API zu verwenden
wäre nicht sonderlich sinnvoll. Genauere Infos hierzu könnte uns wahrscheinlich nur das PB-Team geben.
Freizeitcoder hat geschrieben:In der Hilfe habe ich dazu keine Bemerkung gefunden. (Auch einer der Punkte die ich noch ausprobieren muß.)
das stimmt allerdings. Auch eine Suche im englischen Board verlief bisher erfolglos.

Schon mal darüber nachgedacht, eine 'professionelle' Lösung in Form einer richtigen Datenbank (beispielsweise SQLite) zu verwenden?

Grüße ... Kiffi
a²+b²=mc²
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Linked mit Struktur speichern (OOP)

Beitrag von Kaeru Gaman »

Freizeitcoder hat geschrieben:Am meisten Kopfzerbrechen macht mir das Feld "Zubereitung". Wie schon erwähnt worden ist, kann dieses Feld von "sehr kurz" bis "Herr der Ringe war ein Dreck dagegen" reichen.
ich seh das problem nicht.
die Länge der Strings ist absolut unerheblich, solange du nicht mit FixStrings arbeitest,
weil du sie sowieso direkt als Strings speichern musst und die Datei nur Seriell verarbeiten kannst.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Linked mit Struktur speichern (OOP)

Beitrag von STARGÅTE »

So Freizeitcoder, ich habe nun mal eine Procedure (eigentlich ein Macro) für deine Ansprüche geschrieben:

Code: Alles auswählen

Macro WriteLinkedList(File, LinkedListName, LinkedListStructure)
  WriteLong(File, ListSize(LinkedListName()))
  ForEach LinkedListName()
    *WriteLinkedList_Buffer.String = @LinkedListName()
    While *WriteLinkedList_Buffer - @LinkedListName() < SizeOf(LinkedListStructure)
      WriteString(File, *WriteLinkedList_Buffer\s) : WriteCharacter(File, 0)
      *WriteLinkedList_Buffer + 4
    Wend
  Next
EndMacro

Macro ReadLinkedList(File, LinkedListName, LinkedListStructure)
  WriteLinkedList_StringElements = SizeOf(LinkedListStructure)/4
  ClearList(LinkedListName())
  WriteLinkedList_Elements = ReadLong(File)
  While ListSize(LinkedListName()) < WriteLinkedList_Elements
    *WriteLinkedList_Buffer.String = AddElement(LinkedListName())
    While *WriteLinkedList_Buffer - @LinkedListName() < SizeOf(LinkedListStructure)
      *WriteLinkedList_Buffer\s = ReadString(File)
      *WriteLinkedList_Buffer + 4
    Wend
  Wend
EndMacro
Diese sind so zu benutzen (Beispiel):

Code: Alles auswählen

Structure StringStruc
  String1$
  String2$
  String3$
EndStructure

NewList Test.StringStruc()

AddElement(Test())
  Test()\String1$ = "Hallo"
  Test()\String2$ = "Du"
  Test()\String3$ = "Da"
AddElement(Test()) 
  Test()\String1$ = "Unglaublich"
  Test()\String2$ = "Mega"
  Test()\String3$ = "Schön"

CreateFile(1, "Test.txt")
  WriteLinkedList(1, Test, StringStruc)
CloseFile(1)

ClearList(Test())

ReadFile(1, "Test.txt")
  ReadLinkedList(1, Test, StringStruc)
CloseFile(1)

ForEach Test()
  Debug Test()\String1$
  Debug Test()\String2$
  Debug Test()\String3$
Next
Wie du siehst, wird bei ReadLinkedList/WriteLinkedList die File-Nummer übergeben, dann der LinkedListName (also wirklich nur der name ohne Klammern) und dann noch der StructureName.

ReadLinkedList darfst du jedoch nur benutzen, wenn du das auszulesende auch mit WriteLinkedList geschrieben hast ...

Es ist nur für Structuren nur ausschließlich Strings haben, aber egal wie viele, bei ReadLinkedList wird diese immer komplett gelöscht!
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Freizeitcoder
Beiträge: 35
Registriert: 24.09.2009 13:31
Wohnort: München

Re: Linked mit Struktur speichern (OOP)

Beitrag von Freizeitcoder »

Wow, Du hast dir ja richtig Arbeit gemacht. Ich werde mich später gleich mal hinsetzen und den Code verinnerlichen.
Danke Dir.

Gruß
Freizeitcoder
Beiträge: 35
Registriert: 24.09.2009 13:31
Wohnort: München

Re: Linked mit Struktur speichern (OOP)

Beitrag von Freizeitcoder »

Hallo zusammen,

um allen die auf diesen Thread stoßen, das Ergebnis meiner Überlegungen zu hinterlassen poste ich die Lösung für die ich mich letztendlich entschieden habe.

Code: Alles auswählen

Structure meals
	name.s
	ingredient.s
	preparation.s
	time.f
	people.l
	pic.s
EndStructure
Global NewList meal.meals()

Structure wines
	name.s
	sort.s
	color.s
	description.s
EndStructure	
Global NewList wine.wines()

;---------------------------------------------- load data
Procedure load_data(filename.s)
OpenPreferences(filename.s)		
	number.l = ReadPreferenceLong("number_meal",0) 		;Anzahl der Mahlzeiten auslesen
	For i=0 To number
		AddElement(meal())
		meal()\name = ReadPreferenceString("name"+Str(i),"0")
		meal()\ingredient = ReadPreferenceString("ingredient"+Str(i),"0")
		meal()\preparation = ReadPreferenceString("preparation"+Str(i),"0")
		meal()\time = ReadPreferenceFloat("time"+Str(i),0)
		meal()\people = ReadPreferenceLong("people"+Str(i),0)
		meal()\pic = ReadPreferenceString("pic"+Str(i),"0")
	Next
	number = ReadPreferenceLong("number_wine",0) 		;Anzahl der Weine auslesen
	For i=0 To number
		AddElement(wine())							
		wine()\name = ReadPreferenceString("name"+Str(i),"0")
		wine()\sort = ReadPreferenceString("sort"+Str(i),"0")
		wine()\color = ReadPreferenceString("color"+Str(i),"0")
		wine()\description = ReadPreferenceString("description"+Str(i),"0")
	Next		
ClosePreferences()	
EndProcedure

;---------------------------------------------- save data
Procedure save_data(filename.s)
CreatePreferences(filename.s)	
	number.l = ListSize(meal())
	WritePreferenceLong("number_meal",number)			;Anzahl der Mahlzeiten ermitteln und speichern
	FirstElement(meal())								;auf das erste Element springen
	For i=0 To number                                                             ;könnte auch mit "foreach" gelöst werden
		WritePreferenceString("name"+Str(i),meal()\name)
		WritePreferenceString("ingredient"+Str(i),meal()\ingredient)
		WritePreferenceString("preparation"+Str(i),meal()\preparation)
		WritePreferenceFloat("time"+Str(i),meal()\time)
		WritePreferenceLong("people"+Str(i),meal()\people)
		WritePreferenceString("pic"+Str(i),meal()\pic)
		NextElement(meal())
	Next
	number = ListSize(wine())
	WritePreferenceLong("number_wine",number)			;Anzahl der Weine ermitteln und speichern
	FirstElement(wine())								;auf das erste Element springen
	For i=0 To number
		WritePreferenceString("name"+Str(i),wine()\name)
		WritePreferenceString("sort"+Str(i),wine()\sort)
		WritePreferenceString("color"+Str(i),wine()\color)
		WritePreferenceString("description"+Str(i),wine()\description)
		NextElement(wine())
	Next
ClosePreferences()
EndProcedure
Aufgerufen wird das ganze dann im Programm mit folgenden Befehlen:

Code: Alles auswählen

load_data("data.pref")
save_data("data.pref")
Sorry für die Codemenge, aber es kamen so viele gute Entwürfe, daß ich ein vollständiges Ergebnis hinterlassen wollte. Ich habe mich in erster Linie für eine Lösung entschieden, die ich als PureAnfänger durchblicken kann, und wo ich mich einigermaßen sicher fühle. Die Funktion ist nun doch spezifisch und nicht universal einsetzbar geworden. Trotzdem bin ich mit dem Ergebnis sehr zufrieden. Sobald ich ein wenig besser geworden bin, sehe ich mir den Thread nochmal an, und knöpfe mir die eleganteren Lösungen vor ;) Danke nochmal an alle die sich beteiligt haben.

Gruß
Antworten