SizeOf( structure ) / ASCII-Größe unter Unicode ermitteln?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von Josh »

Hast du meinen letzten Beitrag bis zum Ende gelesen? Dann hast du deine 48 Byte.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
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:

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von NicTheQuick »

Etwas umständlicher, aber so geht's auch:

Code: Alles auswählen

Structure strBHC_Header
	sMagicWord.a[4]
	wDatabaseType.w
	sUserdefinedDatabaseTypecode.a[8]
	lVersion.l
	sDescription.a[30]
EndStructure

Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode

Define bhc.strBHC_Header

; Schreiben
PokeS(@bhc\sDescription, "Hallo", 30, #PB_Ascii)

; Lesen
Debug PeekS(@bhc\sDescription, 30, #PB_Ascii)
Bild
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von Sicro »

@NicTheQuick:
Unsere Codes sind sehr ähnlich :mrgreen:
Ich habe gar nicht gewusst, dass man die eckigen Klammern "[0]" später auch weglassen kann.

@Kurzer:
Vermutlich weißt du das schon, aber mit den Codes von NicTheQuick und mir, kannst du die Struktur ganz einfach in einem Rutsch von einer Datei einlesen oder in eine Datei schreiben:

Code: Alles auswählen

WriteData(File, @Header, SizeOf(strBHC_Header))
ReadData(File, @Header, SizeOf(strBHC_Header))
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von Kurzer »

Es gibt ja dann doch so einige Ansätze wie man das lösen kann.
Vielen Dank für Eure Vorschläge. <)

@Josh: Ja, ich habe den Teil gelesen. "sDescription.s{30/SizeOf(Character)}" ist eine andere Schreibweise wie für "sDescription.a[30]". Es kommen halt in beiden Fällen immer 30 Byte Platz bei raus.

Allerdings muss man auch in Deinem Fall auf Peek und Poke für das Lesen und Schreiben zurückgreifen.
Ich überlege noch was für mich am optimalsten ist. Die gesamte Struktur mit einem WriteData() zu schreiben hat seinen Reiz. Beim Einlesen jedoch lese ich die Felder einzeln ein, um sie vor dem endgültigen Laden der Datei einer logischen Prüfung zu unterziehen.

Ich kann auch eine zweite Version der Struktur definieren, die dann entsprechend mit ".a[30]" arbeitet statt mir ".s[30]" und diese Struktur ausschließlich für die Größenermittlung per SizeOf() nutzen.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
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:

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von NicTheQuick »

Ich würde die Struktur nicht Stück für Stück einlesen, sondern an einem Stück. Ob die Daten Sinn ergeben, kannst du später immer noch überprüfen. Der Vorteil einer festen Strukturgröße ist ja, dass du sie am Stück und damit sehr schnell einlesen kannst. Und wenn du davor die Strukturgröße in die Datei schreibst, dann weißt du auch, dass es passen muss.
Bild
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von mk-soft »

Habe mal zwei Macros geschrieben um vereinfacht ASCII Arrays zu lesen und zu schreiben,
und die Sache mit WriteData und ReadData...

Code: Alles auswählen

Structure strBHC_Header
   sMagicWord.a[4]
   wDatabaseType.w
   sUserdefinedDatabaseTypecode.a[8]
   lVersion.l
   sDescription.a[30]
EndStructure

Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode

Global bhc.strBHC_Header
Global bhc2.strBHC_Header

Macro SetA(Destination, Text)
  PokeS(@Destination, Text, SizeOf(Destination), #PB_Ascii)
EndMacro

Macro GetA(Source)
  PeekS(@Source, SizeOf(Source), #PB_Ascii)
EndMacro

Debug SizeOf(bhc\sMagicWord)

; Schreiben
SetA(bhc\sMagicWord, "12345678")
SetA(bhc\sDescription, "Hallo")

If CreateFile(0, GetHomeDirectory() + "TestData.bin")
  Debug "Save datablock"
  WriteData(0, bhc, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

; Lesen
If ReadFile(0, GetHomeDirectory() + "TestData.bin")
  Debug "Read datablock"
  ReadData(0, bhc2, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

Debug GetA(bhc2\sMagicWord)
Debug GetA(bhc2\sDescription)

CallDebugger
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von Kurzer »

@NicTheQuick: Ja, ich geb Dir Recht.

Bei meinen Tests bin ich auch auf den neu eingeführten Befehl Ascii($Text) gestoßen, aber so ganz versteh ich nicht was der anders macht, als z.B. ein entsprechendes PokeS(... #PB_Ascii). Ist leider nur aufwändiger mit Ascii().

Code: Alles auswählen

Structure Struct
	sText.s{6 / SizeOf(Character)}
EndStructure

Global Test.Struct

; Version mit Poke...
PokeS(@Test\sText, "Hallo!", 6, #PB_Ascii)

ShowMemoryViewer(@Test\sText, 100)
CallDebugger

; Version mit Ascii()...
*mem = Ascii("012345")
CopyMemory(*mem, @Test\sText, 6)
FreeMemory(*mem)

ShowMemoryViewer(@Test\sText, 100)
CallDebugger
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von Kurzer »

mk-soft hat geschrieben:Habe mal zwei Macros geschrieben um vereinfacht ASCII Arrays zu lesen und zu schreiben,
und die Sache mit WriteData und ReadData...
Danke für Deine Mühe. Das funktioniert aber offenbar nicht mehr, wenn man als Strukturvariable eine Pointervariable nutzt. Ich nutze ja Deine OOP-BaseClass für dieses Projekt und die Referenzierung der Strukturen beginnt damit immer mit "*this\..."

Damit klappt das nicht mehr. Das kannst Du prüfen indem Du in Deinem Code aus der Strukturvariable "bhc2" ein "*bhc2" machst.

Code: Alles auswählen

Structure strBHC_Header
   sMagicWord.a[4]
   wDatabaseType.w
   sUserdefinedDatabaseTypecode.a[8]
   lVersion.l
   sDescription.a[30]
EndStructure

Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode

Global bhc.strBHC_Header
Global *bhc2.strBHC_Header

Macro SetA(Destination, Text)
  PokeS(@Destination, Text, SizeOf(Destination), #PB_Ascii)
EndMacro

Macro GetA(Source)
  PeekS(@Source, SizeOf(Source), #PB_Ascii)
EndMacro

Debug SizeOf(bhc\sMagicWord)

; Schreiben
SetA(bhc\sMagicWord, "1234")
SetA(bhc\sDescription, "Hallo")

If CreateFile(0, "D:\TestData.bin")
  Debug "Save datablock"
  WriteData(0, bhc, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

; Lesen
If ReadFile(0, "D:\TestData.bin")
  Debug "Read datablock"
  ReadData(0, *bhc2, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

Debug GetA(*bhc2\sMagicWord)
Debug GetA(*bhc2\sDescription)

CallDebugger
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von Sicro »

@Kurzer:

Der neue Befehl Ascii() (gibt auch noch UTF8() ) macht intern nichts anderes als das:

Code: Alles auswählen

Procedure.i Ascii2(String$)
  Protected NeededMemorySize, *Memory
  
  NeededMemorySize = StringByteLength(String$, #PB_Ascii)
  NeededMemorySize + 1 ; For the null-character on the end of the string (ascii/utf8: 1 byte, unicode: 2 bytes)
  *Memory = AllocateMemory(NeededMemorySize)
  If *Memory
    PokeS(*Memory, String$, -1, #PB_Ascii)
  EndIf
  
  ProcedureReturn *Memory
EndProcedure
Der Befehl ist also ein Kürzel für obigen Code.

Bei meinem vorherigem Code habe ich einen Fehler gemacht. PokeS() schreibt noch das Null-Zeichen hinter den String.

Code: Alles auswählen

; Schreiben
PokeS(@Header\sMagicWord[0], "ABCD", -1, #PB_Ascii)
ersetzen durch:

Code: Alles auswählen

; Schreiben
PokeS(@Header\sMagicWord[0], "ABCD", -1, #PB_Ascii | #PB_String_NoZero)
Andernfalls schreibt PokeS() in diesem Fall in wDatabaseType.w rein, wenn du bei sMagicWord.a[4] alle 4 Zeichenplätze voll schreibst.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Beitrag von mk-soft »

Kurzer hat geschrieben: Damit klappt das nicht mehr. Das kannst Du prüfen indem Du in Deinem Code aus der Strukturvariable "bhc2" ein "*bhc2" machst.
*bhc2 ist ja nur ein Pointer auf eine Speichergebiet. Wenn Du keinen Speicher anforderst geht das natürlich nicht

Code: Alles auswählen

*bhc2 = AllocateStructure(strBHC_Header)
; Lesen
If ReadFile(0, "D:\TestData.bin")
  Debug "Read datablock"
  ReadData(0, *bhc2, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf
P.S.
In den Modul BaseClass wird ja bei anlegen eines Objektes Speicher angelegt.
Ist allerdings in der Struktur wieder ein Pointer definiert, so muss beim Initialisieren (AsInitializeObject) selber dieser Speicher angefordert werden
und beim Objekt freigeben (AsDisposeObjekt) wieder freigegeben werden.
Kann ja mal ein Beispiel schreiben...
Zuletzt geändert von mk-soft am 24.01.2018 22:22, insgesamt 1-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten