Seite 1 von 2
nummer eines structurefeldes
Verfasst: 06.08.2013 10:20
von BSP
Hallo Allerseits.
Innerhalb meines Prg arbeite ich mit Structuren.
Zum abspeichern in einer Datei möchte ich nun alle Ergebnisse der Structur zu einem Satz zusammenfügen.
Um den Satz nun nicht in lauter einzelschritten zusammen zu fügen,
möchte ich das gerne in einer Schleife erledigen.
Gibt es dazu einen weg, die Nummer eines Structurefeldes zu erkennen?
Hier mal ein Beispiel, damit Ihr seht, was ich meine:
Code: Alles auswählen
Structure worte
wort1.s
wort2.s
wort3.s
EndStructure
Define a.worte
Define satz.s
a\wort1 = "Test1"
a\wort2 = "Test2"
a\wort3 = "Test3"
; Version 1 : Alles einzeln Zusammenfügen
satz = a\wort1 +Chr(30)
satz + a\wort2 +Chr(30)
satz + a\wort3 +Chr(30)
Debug satz
; Version 2 : Alles durch eine Schleife zusammenfügen
satz = ""
For i = 1 To anzahl_structurefelder
satz + a\structurefeld_i +Chr(30)
Next
Debug satz
Gruß: Bernd
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 10:27
von c4s
In dem Fall lohnt es sich eventuell die Strukturierung zu überdenken. Mit einer Liste geht es wunderbar:
Code: Alles auswählen
Structure worte
List wort.s()
EndStructure
Define a.worte
Define satz.s
AddElement(a\wort()) : a\wort() = "Test1"
AddElement(a\wort()) : a\wort() = "Test2"
AddElement(a\wort()) : a\wort() = "Test3"
ForEach a\wort()
satz + a\wort() +Chr(30)
Next
Debug satz
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 10:36
von NicTheQuick
Die schöne Version wäre offensichtlich ein statisches Array in der Structure:
Code: Alles auswählen
Structure worte
wort.s[3]
EndStructure
Define a.worte
Define satz.s
a\wort[0] = "Test1"
a\wort[1] = "Test2"
a\wort[2] = "Test3"
; Version 2 : Alles durch eine Schleife zusammenfügen
satz = ""
For i = 0 To 2
satz + a\wort[i] + Chr(30)
Next
Debug satz
Die nicht so schöne Version funktioniert mit Pointern und funktioniert auch nur, wenn in der Structure tatsächlich nur Strings nacheinander vorkommen und sonst nichts.
Code: Alles auswählen
Structure worte
wort1.s
wort2.s
wort3.s
EndStructure
Define a.worte
Define satz.s
a\wort1 = "Test1"
a\wort2 = "Test2"
a\wort3 = "Test3"
; Version 2 : Alles durch eine Schleife zusammenfügen
satz = ""
Define *wortPointer.String = @a
For i = 1 To 3
satz + *wortPointer\s + Chr(30)
*wortPointer + SizeOf(String)
Next
Debug satz
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 10:43
von BSP
Hallo c4s, Hallo Nick
Das es auch andere Möglichkeiten gibt, ist mir klar.
Ich könnte auch mit arrays arbeiten und brauche die dann nur zu durchlaufen.
Aber ich habe mein Beispiel mit bedacht so gewählt.
Es ist eben nur ein Beispiel.
Tatsächlich ist meine structur natürlich umfangreicher.
In dem Zusammenhang noch eine weitere Frage:
Man müsste natürlich auch die Art des Structurfeldes erkennen:
Beispiel:
Code: Alles auswählen
Structure worte
wort1.s
wort2.s
wort3.s
EndStructure
Define a.worte
Define satz.s
a\wort1 = "Test1"
a\wort2 = "Test2"
a\wort3 = "Test3"
; Version 1 : Alles einzeln Zusammenfügen
satz = a\wort1 +Chr(30)
satz + a\wort2 +Chr(30)
satz + a\wort3 +Chr(30)
Debug satz
; Version 2 : Alles durch eine Schleife zusammenfügen
satz = ""
For i = 1 To anzahl_structurefelder
If structurefeld = interger
;satz + Str(a\structurefeld_i)
ElseIf structurefeld = float
;satz + StrF(a\structurefeld_i)
Else
;satz + a\structurefeld_i
endif
satz + Chr(30)
Next
Debug satz
Und ausserdem ginge mir in Eurem Beispiel ja die Übersichtlichkeit der Namensgebung verloren.
"a\feldname"
Gruß: bernd
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 10:51
von BSP
Und noch ein PS an Nick.
Dein Beispiel mit dem Pointer geht schon gut in meine Gedachte Richtung.
Wir hatten uns beim schreiben gerade überschnitten, deshalb meine nachgesetzte Antwort/Frage.
Gibt es noch eine Möglichkeit die Art des Feldes zu erkennen?
Gruß: Bernd
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 10:53
von NicTheQuick
Tja, das geht aber leider nicht so einfach. Ich habe so etwas ähnliches mal programmiert um ganze Structures über's Netzwerk zu senden oder in Dateien zu schreiben oder daraus zu lesen. Damit das klappt, hatte ich neben der eigentlichen Structure noch einen String, der sozusagen die Structure in einfachen Buchstaben darstellte und gleichzeitig zu den Structurefeldern in einer Schleife durchlaufen wurde. So wusste man wie viele Bytes man pro Feld weiter gehen musste und wie man es ausliest. Der Thread dazu ist hier:
Write-, ReadStructure (3. Update)
Aber es ist in PureBasic nicht vorgesehen über Structure-Felder zu iterieren, die verschiedene Typen haben. Das müsste dann ja schon zur Übersetzungszeit geschehen, weil zur Laufzeit dein Programm nichts mehr von Structures weiß. Die wurden bis dahin "klein"-kompiliert.
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 11:27
von BSP
@Nick.
hm, ok. Mal nachgrübeln.
Dann werde ich wohl meine komplette structure als Strings machen, auch die Zahlen.
Und dann Dein Beispiel mit SizeOf verwenden.
Ich habe mir Deine Beispiele mal kurz angesehen. (Aber noch nicht alles verstanden).
Und ob ich das sooo kompliziert brauche, denke ich nicht. Smile.
Es geht mir darum, den Datensatz schnell zusammen zu fügen.
Zum Abspeichern oder für vergleichszwecke, ob >etwas< geändert wurde.
Innerhalb des Programms ist es ja gerade ein wertvoller vorteil,
alles schön als wiedererkennbaren namen vorliegen zu haben.
a\der_eine_name
a\der_andere_name
a\und_ein_wert
usw.
Nachteile von "alles als String" ist sicherlich ein etwas grösserer speicherverbrauch und das man zahlen zur Berechnung immer erst mal umwandeln muss.
Aber das ist bei den heutigen Rechnern sicher kein so grosses Problem mehr.
Der Vorteil wäre, grössere Flexibilität im hinblick auf spätere Erweiterungen der Structure.
Ich müsste sonst später vieleicht in mehreren Proceduren Änderungen vornehmen.
Wenn ich alles in einer Schleife zusammenfüge, muss ich das nicht.
Ausser dann beim wieder zurück schreiben.
Vom Datensatz in die Structure.
Na, mal überlegen.
Jedenfalls Gruß & Dank:
Bernd
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 11:39
von STARGÅTE
Hier mal ein etwas komplexeres Beispiel, welches sowas wie Klassen und Methoden benutzt.
Am Anfang definiere ich mir alle möglichen Komponenten die ein Satz haben kann (z.B. Text und Nummer).
Danach definiere ich mir Funktionen zum Hinzufügen und Ausgeben von Komponenten eines Satzes (Block).
Am Ende werden die Satzteile dynamisch zu einem Satz zusammen gebaut, und die Ausgabe des Satzes erfolgt dann über die jeweiligen Methoden, wie eine Komponente zu einem String verarbeitet werden soll.
Code: Alles auswählen
Prototype.s GetItem(*Head)
Structure Head
Get.GetItem
EndStructure
Structure Text Extends Head
String.s
EndStructure
Structure Number Extends Head
Float.f
EndStructure
Structure Block
List *Item.Head()
EndStructure
Global NewList Text.Text()
Global NewList Number.Number()
Procedure.s GetText(*Text.Text)
ProcedureReturn *Text\String
EndProcedure
Procedure.s AddText(*Block.Block, String.s)
AddElement(*Block\Item())
*Block\Item() = AddElement(Text())
Text()\Get = @GetText()
Text()\String = String
EndProcedure
Procedure.s GetNumber(*Number.Number)
ProcedureReturn StrF(*Number\Float)
EndProcedure
Procedure.s AddNumber(*Block.Block, Float.f)
AddElement(*Block\Item())
*Block\Item() = AddElement(Number())
Number()\Get = @GetNumber()
Number()\Float = Float
EndProcedure
Define MyBlock.Block
AddText(MyBlock, "Heute werden es ")
AddNumber(MyBlock, 30.5)
AddText(MyBlock, "°C und es regnet mit einer Wahrscheinlichkeit von ")
AddNumber(MyBlock, 5.25)
AddText(MyBlock, "%.")
Define Output.s
ForEach MyBlock\Item()
Output + MyBlock\Item()\Get(MyBlock\Item())
Next
Debug Output
Re: nummer eines structurefeldes
Verfasst: 06.08.2013 12:00
von NicTheQuick
BSP hat geschrieben:@Nick.
hm, ok. Mal nachgrübeln.
Dann werde ich wohl meine komplette structure als Strings machen, auch die Zahlen.
Und dann Dein Beispiel mit SizeOf verwenden.
<snip>
Nachteile von "alles als String" ist sicherlich ein etwas grösserer speicherverbrauch und das man zahlen zur Berechnung immer erst mal umwandeln muss.
Aber das ist bei den heutigen Rechnern sicher kein so grosses Problem mehr.
Der Vorteil wäre, grössere Flexibilität im hinblick auf spätere Erweiterungen der Structure.
Ich müsste sonst später vieleicht in mehreren Proceduren Änderungen vornehmen.
Wenn ich alles in einer Schleife zusammenfüge, muss ich das nicht.
Ausser dann beim wieder zurück schreiben.
Vom Datensatz in die Structure.
Na, mal überlegen.
Nein, mach das bitte nicht, also überall Strings verwenden. Das ist Quatsch. So programmiert man nicht. Man nutzt für alles den richtigen Datentyp und speichert ihn auch so. Konvertierungen zwischen Strings und Zahlenvariablen sind ellenlangsam und ungenau, z.B. bei Fließkommazahlen, wenn man nicht aufpasst.
Bei imperativen Programmiersprachen wie PureBasic ist es nun mal meist komplizierter wie in objektorientierten Sprachen. Aber da kann man dann ohne viele Tricks nicht viel dagegen machen und muss halt damit leben seine Procedures auch mal anzupassen, wenn sich eine Structure ändert. Aber wenn du alles schön hierarchisch aufbaust, solltest du da kaum Probleme mit haben.
Re: nummer eines structurefeldes
Verfasst: 07.08.2013 11:52
von KeyKon
Eine weitere Möglichkeit, wenn keine Strings dabei sind.
Es ist allerdings möglich fixed Strings zu nutzen, das würde ich aber wirklich nur empfehlen wenn die Länger der Strings ziemlich genau bekannt ist, sonst ist das einfach Platzverschwendung:
Code: Alles auswählen
EnableExplicit
Structure struc
long.l
word.w
float.f
string.s{10}
quad.q
EndStructure
Define var.struc
CompilerIf 0 ;Schreiben
var\long = 11
var\word = 12
var\float = 13.13
var\string = "Vierzehn"
var\quad = 15
If Not CreateFile(0,"D:\testfile")
End
EndIf
WriteData(0,@var,SizeOf(struc))
CloseFile(0)
CompilerElse ;Lesen
If Not ReadFile(0,"D:\testfile")
End
EndIf
ReadData(0,@var,SizeOf(struc))
CloseFile(0)
Debug var\long
Debug var\word
Debug var\float
Debug var\string
Debug var\quad
CompilerEndIf