@NicTheQuick
Danke. Sehr interessanter Weg. Zum Verstehen habe ich mir erlaubt, Deinen Code auseinanderzunehmen und möglichst übersichtlich darzustellen.
Das Verfahren könnte Grundlage für eine entsprechende native Funtion in PB sein. Der Compiler kennt ja sogar den Typ eines jeden Strukturelementes, sodass die zusätzliche Ablage des "Bauplans" der Struktur in einer Stringvariablen überflüssig wäre.
Zwei neue Funktionen also :
WriteDataStructure() und
ReadDataStructure().
Code: Alles auswählen
; * Methode von NicTheQuick zur Speicherung von Strukturen mit Strings
; * hier : das Speichern der Daten in eine Datei
; - statt des sinnlos gewordenen Pointers auf den eigentlichen Stringinhalt wird
; dessen Länge als Long in die Datei gespeichert
; - der Inhalt des Strings wird daran angehängt
; - wollte man ein Array oder einen LinkedList auf diese Art speichern, müsste jedes
; Mitglied des Arrays bzw. der Liste in die Strukturvariable "Var" umgespeichert werden
Define.s out ; Hilfsstring für Messagerequester
Define.s Struc_Strukt = "bwlqsfsd" ; Der "Bauplan" der Struktur in einem String
Structure Strukt ; Daten-Struktur
Byte.b
word.w
Long.l
Quad.q
String1.s
Float.f
String2.s
Double.d
EndStructure
Define.Strukt Var ; Variable mit der Struktur anlegen
Structure AllTypes
StructureUnion
s.s : b.b : c.c : w.w : l.l : f.f : d.d : q.q
EndStructureUnion
EndStructure
Procedure WriteDataStructure(FileId, *Var.AllTypes, *Struc.Character)
Protected length.l
While *Struc\c
Select *Struc\c
Case 'b'
WriteData(FileId, *Var, SizeOf(Byte)) : *Var + SizeOf(Byte)
Case 'c'
WriteData(FileId, *Var, SizeOf(Character)) : *Var + SizeOf(Character)
Case 'w'
WriteData(FileId, *Var, SizeOf(Word)) : *Var + SizeOf(Word)
Case 'l'
WriteData(FileId, *Var, SizeOf(Long)) : *Var + SizeOf(Long)
Case 'f'
WriteData(FileId, *Var, SizeOf(Float)) : *Var + SizeOf(Float)
Case 'd'
WriteData(FileId, *Var, SizeOf(Double)) : *Var + SizeOf(Double)
Case 'q'
WriteData(FileId, *Var, SizeOf(Quad)) : *Var + SizeOf(Quad)
Case 's'
length = Len(*Var\s) : WriteLong(FileId, length)
If length : WriteData(FileId, *Var\l, length) : EndIf
*Var + SizeOf(String)
EndSelect
*Struc + SizeOf(Character)
Wend
EndProcedure
; Datenstruktur füllen
Var\Byte = 123
Var\word = 23432
Var\Long = Date()
Var\Quad = 2468012343344533
Var\String1 = "Hallo du!"
Var\Float = 1234.1234
Var\String2 = "Ich bin NTQ!"
Var\Double = 123456789.123456789
; Datenstruktur abspeichern
If CreateFile(0, "test_structure.txt")
WriteDataStructure(0, @Var, @Struc_Strukt)
CloseFile(0)
EndIf
; Datenstruktur präsentieren
out = "Byte: " + Str(Var\Byte) + #lf$
out + "Word: " + Str(Var\word) + #lf$
out + "Long: " + Str(Var\Long) + #lf$
out + "Quad: " + StrQ(Var\Quad) + #lf$
out + "String1: " + Var\String1 + #lf$
out + "Float: " + Str(Var\Float) + #lf$
out + "String2: " + Var\String2 + #lf$
out + "Double: " + StrD(Var\Double) + #lf$
MessageRequester("Gespeicherte Datenstruktur", out )
; so sieht die Datei aus
RunProgram("test_structure.txt", "", "")
End
Code: Alles auswählen
; Methode von NicTheQuick zur Speicherung von Strukturen mit Strings
; hier : das Einlesen aus einer geschriebenen Datei
; - die Procedure erkennt den String am Bauplan der Struktur, der als String "Struc_Strukt" übergeben wird
; - sie ermittelt die Länge, liest den String ein und speichert ihn in die Struktur-Variable
; - wollte man ein Array oder einen LinkedList auf diese Art füllen, müsste der Inhalt der
; eingelesenen Strukturvariablen "Var" als Mitglied in das Arrays bzw. der Liste umgespeichert werden
Define.s out ; Hilfsstring für Messagerequester
Define.s Struc_Strukt = "bwlqsfsd" ; Der "Bauplan" der Struktur in einem String
Structure Strukt ; Daten-Struktur
Byte.b
word.w
Long.l
Quad.q
String1.s
Float.f
String2.s
Double.d
EndStructure
Define.Strukt Var ; Variable mit der Struktur anlegen
Structure AllTypes
StructureUnion
s.s : b.b : c.c : w.w : l.l : f.f : d.d : q.q
EndStructureUnion
EndStructure
Procedure ReadDataStructure(FileId, *Var.AllTypes, *Struc.Character)
Protected length.l
While *Struc\c
Select *Struc\c
Case 'b'
ReadData(FileId, *Var, SizeOf(Byte)) : *Var + SizeOf(Byte)
Case 'c'
ReadData(FileId, *Var, SizeOf(Character)) : *Var + SizeOf(Character)
Case 'w'
ReadData(FileId, *Var, SizeOf(Word)) : *Var + SizeOf(Word)
Case 'l'
ReadData(FileId, *Var, SizeOf(Long)) : *Var + SizeOf(Long)
Case 'f'
ReadData(FileId, *Var, SizeOf(Float)) : *Var + SizeOf(Float)
Case 'd'
ReadData(FileId, *Var, SizeOf(Double)) : *Var + SizeOf(Double)
Case 'q'
ReadData(FileId, *Var, SizeOf(Quad)) : *Var + SizeOf(Quad)
Case 's'
length = ReadLong(FileId) : *Var\s = Space(length)
ReadData(FileId, @*Var\s, length) : *Var + SizeOf(String)
EndSelect
*Struc + SizeOf(Character)
Wend
EndProcedure
; Datenstruktur aus Datei einlesen
If ReadFile(0, "test_structure.txt")
ReadDataStructure(0, @Var, @Struc_Strukt)
CloseFile(0)
EndIf
; Datenstruktur präsentieren
out = "Byte: " + Str(Var\Byte) + #lf$
out + "Word: " + Str(Var\word) + #lf$
out + "Long: " + Str(Var\Long) + #lf$
out + "Quad: " + StrQ(Var\Quad) + #lf$
out + "String1: " + Var\String1 + #lf$
out + "Float: " + Str(Var\Float) + #lf$
out + "String2: " + Var\String2 + #lf$
out + "Double: " + StrD(Var\Double) + #lf$
MessageRequester("Eingelesene Datenstruktur", out )
End