Wichtig: Offizielle dauerhaftes verhalten!?

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

@jear:

Zum Schreiben einer Struktur in einer Datei und zum Auslesen derselben hab
ich schon vor langer Zeit eine halbwegs elegante Procedure gecodet. Ich
habe sie jetzt nochmal an PB V4.02 angepasst und hier findest du sie:

http://www.purebasic.fr/german/viewtopic.php?t=11492
Bild
Benutzeravatar
jear
Beiträge: 288
Registriert: 17.10.2004 01:59
Wohnort: Ammerland

Beitrag von jear »

@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
Zuletzt geändert von jear am 11.01.2007 14:23, insgesamt 1-mal geändert.
Man ist nie zu alt zum lernen, auch wenn man dabei manchmal alt aussieht!
Marvin
Beiträge: 497
Registriert: 17.07.2005 14:42
Wohnort: Krikkit

Beitrag von Marvin »

Nur so am Rande: Ich bezweifle, dass PB die Quads intern als 2 Longs benutzt, da FASM auch "dq", also das QuadWord bereitstellt. :wink:
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Nun das weiß ich nicht genau, ich erinnere mich nur an etwas, das Fred, Andre oder so mal geschrieben hat, das die Quads keine echten Quads sind, intern (noch) irgendwie anders behandelt werden. Mit der Prozessorten und ASM kenne ich micht nicht aus, aber es wurde mal erwähnt, das "logischer Weise" auf 32bit-Systemen, kein 64bit "direkt" ausgeführt werden kann.
So oder so ähnlich. Was weiß ich schon, Hauptsache das tolle PB läuft wie es sollte :-)
1. Win10
PB6.1
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1755
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

Jear hat geschrieben:Zwei neue Funktionen also : WriteDataStructure() und ReadDataStructure().
Hab ich ebenfalls Fred + freak mit Verweis auf diesen Thread und den schon geposteten Codes vorgeschlagen.
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
Benutzeravatar
jear
Beiträge: 288
Registriert: 17.10.2004 01:59
Wohnort: Ammerland

Beitrag von jear »

@Andre
Habe mal die Routinen in eine Include-Datei gelegt und noch Testprogrämmchen mit Arrays und LinkedLists hinzugefügt.
Auch für das CodeArchiv geeignet.

StoreStructuresWithStrings.zip (3KB)
Zuletzt geändert von jear am 12.01.2007 14:12, insgesamt 2-mal geändert.
Man ist nie zu alt zum lernen, auch wenn man dabei manchmal alt aussieht!
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

Nur als Hinweis, ist aber nicht sonderlich wichtig:

Ich hab die beiden Procedures noch einmal überarbeitet. Jetzt sind sie
kürzer, aber nicht schneller.
Bild
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1755
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

jear hat geschrieben:@Andre
Habe mal die Routinen in eine Include-Datei gelegt und noch Testprogrämmchen mit Arrays und LinkedLists hinzugefügt.
Auch für das CodeArchiv geeignet.

StoreStructuresWithStrings.zip (3KB)
Danke, ist vorgemerkt. :D
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
Gesperrt