Übergabe von Strings per Pointer an Proceduren

Für allgemeine Fragen zur Programmierung mit PureBasic.
lrhe
Beiträge: 6
Registriert: 29.09.2004 18:30

Übergabe von Strings per Pointer an Proceduren

Beitrag 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
Benutzeravatar
wichtel
Beiträge: 150
Registriert: 09.09.2004 08:35
Wohnort: Hattersheim

Beitrag 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$



Zuletzt geändert von wichtel am 29.09.2004 19:05, insgesamt 1-mal geändert.
PB / jaPBe jeweils aktuellste Version, seit 3.62 dabei, XP sp3 de/en & W7 en
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8820
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag 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
lrhe
Beiträge: 6
Registriert: 29.09.2004 18:30

Beitrag 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.
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Dann fehlt vermutlich am Anfang des Codes noch folgender Teil.

Code: Alles auswählen

Structure STRING
 s.s
EndStructure
MfG Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Falko hat geschrieben:Dann fehlt vermutlich am Anfang des Codes noch folgender Teil.

Code: Alles auswählen

Structure STRING
 s.s
EndStructure
MfG Falko
STRING ist doch eine vordefinierte Structure...
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
lrhe
Beiträge: 6
Registriert: 29.09.2004 18:30

Beitrag 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
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Deeem2031 hat geschrieben:
Falko hat geschrieben:Dann fehlt vermutlich am Anfang des Codes noch folgender Teil.

Code: Alles auswählen

Structure STRING
 s.s
EndStructure
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
Bild
Win11 Pro 64-Bit, PB_6.11b1
lrhe
Beiträge: 6
Registriert: 29.09.2004 18:30

Beitrag von lrhe »

Hui, hab grad geantwortet aber sie taucht nicht auf, passiert sowas ab und zu?

Also, ihr seid Helden!!! :D
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
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8820
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag 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ß! :allright:
Antworten