Seite 2 von 2

Re: Linked mit Struktur speichern (OOP)

Verfasst: 07.10.2009 13:01
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

Re: Linked mit Struktur speichern (OOP)

Verfasst: 07.10.2009 13:10
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.

Re: Linked mit Struktur speichern (OOP)

Verfasst: 07.10.2009 14:36
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!

Re: Linked mit Struktur speichern (OOP)

Verfasst: 07.10.2009 15:22
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ß

Re: Linked mit Struktur speichern (OOP)

Verfasst: 07.10.2009 21:36
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ß