Seite 1 von 2
Übergabe von Strings per Pointer an Proceduren
Verfasst: 29.09.2004 18:49
von lrhe
Hallo,
komme mit den Pointer's nicht weiter. Hab leider in der Hilfe und im Forum nicht soviel gefunden:
Möchte einen(mehrere) String(s) im Hauptprogramm per Pointer an eine Procedur übergeben, sodass sie dort direkt modifiziert werden können. Klappt noch so, egal wie ich's probiere. Hier im Bsp. scheitert der Aufruf der Proc mit "String erwartet...":
Code: Alles auswählen
;Test Übergabe Stringpointer an Procedure
str.s="abcdefg"
;-----------------------
Procedure mytest(*mystr.s)
tmp.s=""
tmp.s=Left(*mystr,2) ;"ab" aus 'str' in tmp legen
Debug *mystr +", "+tmp
tmp=tmp+"12345" ;tmp auf "ab12345" ergänzen
Debug *mystr +", "+tmp
*mystr=tmp ;tmp zurück in 'str'
Debug *mystr +", "+tmp
EndProcedure
;------------------------
mytest(@str) ;Übergabe Pointer, Fehler!!! :twisted:
result=MessageRequester("Test",str,0) ;soll "ab12345" liefern
End
Eigentlich wollte ich auch LinkedLists per Pointer übergeben, hab aber gelesen, dass das nicht geht?! Ziel ist die Über-/Bearb./Rückgabe langer Datenfelder, vielleicht ja auch als Array mit Pointer?! Die String-Übergabe hab ich nun alternativ verwenden wollen, um das Feld als TokenString zu übergeben und in der Prozedur um Elemente zu ergänzen.
Danke für Eure Hilfe und Tip's!!!
Gruß, Lutz
PS: PB-Version 3.3 (leider noch so'ne ältere TOPOS-KaufCD-Version)
Edit by NicTheQuick: Code-Tags gesetzt
Verfasst: 29.09.2004 19:01
von wichtel
Versuche es mal mit der Übergabe eines Pointers auf eine Struktur mit Strings. Dann sollte es gehen.
Code: Alles auswählen
Structure DATEN
feld1$
feld2$
feld3$
feld4$
EndStructure
nurso.DATEN
Procedure MachWas(*p.DATEN)
*p\feld1$="Das"
*p\feld2$="ist"
*p\feld3$="ein"
*p\feld4$="Test"
EndProcedure
Debug nurso\feld1$
Debug nurso\feld2$
Debug nurso\feld3$
Debug nurso\feld4$
MachWas(@nurso)
Debug nurso\feld1$
Debug nurso\feld2$
Debug nurso\feld3$
Debug nurso\feld4$
Verfasst: 29.09.2004 19:05
von NicTheQuick
Das geht leider nicht so einfach, wie du dir das vorstellst. Hier wäre meine Variante. Das Problem ist wohl, dass die Stringfunktionen mit der Pointervariante nicht so wirklich arbeiten können. Man muss also immer noch [c]PokeS()[/c] und [c]PeekS()[/c] nehmen.
Code: Alles auswählen
;Test Übergabe Stringpointer an Procedure
Global str.s
str.s="abcdefg"
;-----------------------
Procedure mytest(*mystr.STRING)
Protected tmp.s
tmp = PeekS(*mystr, 2)
Debug PeekS(*mystr) + ", " + tmp
tmp = tmp + "12345" ; tmp auf "ab12345" ergänzen
Debug PeekS(*mystr) + ", " + tmp
PokeS(*mystr, tmp)
Debug PeekS(*mystr) + ", " + tmp
EndProcedure
;------------------------
mytest(@str) ; Übergabe Pointer, Fehler!!! :twisted:
result = MessageRequester("Test", str, 0) ; soll "ab12345" liefern
End
Verfasst: 29.09.2004 19:28
von lrhe
Danke für eure schnellen Antworten. Mein 3.3 Compiler scheitert aber auch beim probieren des Bsp. mit PeekS schon an der Zeile zum Aufruf der Funktion und sagt:
mytest(@str) ---> liefert: Bad parameter type: a string is expected
Übergebe ich nicht mit @var einen pointer auf var? Das ist dann zwar ein long, aber dafür hab ich doch im Kopf der Procedur den *, damit er weiß, dass ein Pointer kommt?
Über die Struktur werd' ich's nochmal separat probieren, mach das ganze m.E. aber etwas kompliziert.
Verfasst: 29.09.2004 19:41
von Falko
Dann fehlt vermutlich am Anfang des Codes noch folgender Teil.
MfG Falko
Verfasst: 29.09.2004 19:48
von Deeem2031
Falko hat geschrieben:Dann fehlt vermutlich am Anfang des Codes noch folgender Teil.
MfG Falko
STRING ist doch eine vordefinierte Structure...
Verfasst: 29.09.2004 19:52
von lrhe
Na, hoffentlich missverstehen wir uns da nicht: will einfach nur einen String, deklariert im o.g. Beispiel über str.s mittels Pointer an eine Funktion zur Bearbeitung übergeben. Da ist vielleicht nur ein Schreibfehler?!
Wie holt ihr euch denn mehrere Funktionsergebnisse zurück? Nur über globale Variablen, die in der Prozedur weitergelten? Das will ich vermeiden, da ich verschiedene Stringvariablen an die eine Funktion übergeben will.
Gruß,
Lutz
Verfasst: 29.09.2004 20:01
von Falko
Deeem2031 hat geschrieben:Falko hat geschrieben:Dann fehlt vermutlich am Anfang des Codes noch folgender Teil.
MfG Falko
STRING ist doch eine vordefinierte Structure...
Ich habe mir den Ordner Purebasic "CD TOPO-Version Ver. 3.3" mal auf meine Platte kopiert und den obigen Code ausgeführt. Danach ist
.STRING
nicht in einer Structure definiert und deshalb der Fehler. Fügt man die Structur unter PB 3.3 hinzu, arbeitet es genauso wie in PB 3.91.
MfG Falko
Verfasst: 29.09.2004 20:12
von lrhe
Hui, hab grad geantwortet aber sie taucht nicht auf, passiert sowas ab und zu?
Also, ihr seid Helden!!!
Es klappt mit der Struktur .STRING und dem PeekS. Aber ganz normal ist das doch nicht, was man da für Verrenkungen tun muss. Nun, funktionieren tut's.
Gibt's so'n Trick mit der Struktur auch für Array's oder LinkedLists?
Nochmal vielen Dank!
Lutz
Verfasst: 29.09.2004 20:50
von NicTheQuick
Bei Arrays ist es ganz einfach Werte zu ändern.
Aber erstmal ein Beispiel um mehrere Werte von einer Procedure zurückzubekommen. Sinnlos, aber sicherlich nützlich. (Hmmm, unlogischer Satz)
Code: Alles auswählen
Structure IR_Ex
Text.s
Length.l
Ok.l
EndStructure
Procedure InputRequester_Ex(Title.s, Message.s, DefaultString.s, *Out.IR_Ex)
Protected Result.s
Result.s = InputRequester(Title, Message, DefaultString)
If *Out
*Out\Text = Result
*Out\Length = Len(Result)
If *Out\Length
*Out\Ok = #True
Else
*Out\Ok = #False
EndIf
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
InputRequester_Ex("Hallo", "Gib was ein.", "(da steht nix)", @Result.IR_Ex)
If Result\Ok
MessageRequester("Hallo", "Es wurde folgender Text eingegeben:" + #LFCR$ + Result\Text + #LFCR$ + "Er hat die Länge " + Str(Result\Length) + " Bytes.")
Else
MessageRequester("Hallo", "Es wurde nichts eingegeben")
EndIf
Und hier nun das Beispiel für Arrays:
Code: Alles auswählen
#Entries = 10
Structure TestStruc
Long.l
String.s
Float.f
EndStructure
Dim Array.TestStruc(#Entries - 1)
Procedure ReadArray(*Array.TestStruc, Entries.l)
While *Array And Entries
Debug *Array\Long
Debug *Array\String
Debug *Array\Float
Entries - 1
*Array + SizeOf(TestStruc)
Wend
EndProcedure
Procedure WriteArray(*Array.TestStruc, Entries.l)
Protected a.l
While *Array And Entries
a + 1
*Array\Long = a
*Array\String = "Value: " + Str(a)
*Array\Float = 1 / a
*Array + SizeOf(TestStruc)
Entries - 1
Wend
EndProcedure
WriteArray(@Array(), #Entries)
ReadArray(@Array(), #Entries)
Bei LinkedLists ist es problematisch, da du hier nur auslesen und ändern kannst, aber keine Elemente hinzufügen oder löschen kannst. Das geht höchstens bedingt. Aber diese Bedingung will ich hier erstmal nicht aufführen. Du kannst dir auch mal anschauen, was ich dir mit der Konstanten [c]#Modus[/c] sagen will.
Code: Alles auswählen
#Entries = 10
Structure TestStruc
Long.l
String.s
Float.f
EndStructure
NewList LL.TestStruc()
For a.l = 1 To #Entries
If AddElement(LL())
LL()\Long = a
LL()\String = "Value: " + Str(a)
LL()\Float = 1 / a
EndIf
Next
Procedure ReadLinkedList(*FirstElement.TestStruc)
While *FirstElement <> 8
Debug *FirstElement\Long
Debug *FirstElement\String
Debug *FirstElement\Float
*FirstElement = PeekL(*FirstElement - 8) + 8
Wend
EndProcedure
Procedure ChangeLinkedList(*FirstElement.TestStruc)
While *FirstElement <> 8
*FirstElement\Long * 100
*FirstElement\String = "Value: " + Str(a)
*FirstElement\Float = 1 / *FirstElement\Long
*FirstElement = PeekL(*FirstElement - 8) + 8
Wend
EndProcedure
#Modus = 0
If #Modus
ReadLinkedList(FirstElement(LL()) + 8)
Else
FirstElement(LL())
ReadLinkedList(@LL())
EndIf
If #Modus
ChangeLinkedList(FirstElement(LL()) + 8)
Else
FirstElement(LL())
ChangeLinkedList(@LL())
EndIf
Debug "----------------------------------------"
If #Modus
ReadLinkedList(FirstElement(LL()) + 8)
Else
FirstElement(LL())
ReadLinkedList(@LL())
EndIf
Viel Spaß!
