ReplaceString(), FindString() unschlagbar?

Für allgemeine Fragen zur Programmierung mit PureBasic.
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: ReplaceString(), FindString() unschlagbar?

Beitrag von SMaag »

Ich hab's geschafft! Es geht ohne Public _AddQuotes_
Man muss nur die Adresszuweisung in das Modul verlegen. Das ist alles!
Hier der geänderte Code

Code: Alles auswählen

DeclareModule Quotes
  #STR_CHAR_DoubleQuote = 34    ; "
  #STR_CHAR_SingleQuote = 39    ; '
  
  
  Declare.s AddQuotes_Classic(String$, cQuote.c=#STR_CHAR_DoubleQuote)

  Prototype.s AddQuotes(String$, cQuote.c=#STR_CHAR_DoubleQuote)
  ; Declare.s _AddQuotes_(*String, cQuote.c=#STR_CHAR_DoubleQuote) ; _AddQotes_ nur noch Private
  Define MyAddQuotes.AddQuotes  ; = @_AddQuotes_() ; die Adresszuweisung muss in's Modul
  Define OhterAddQuotes.AddQuotes ; nur um zu sehen ob das geht! 
EndDeclareModule


Module Quotes

  Procedure.s AddQuotes_Classic(String$, cQuote.c=#STR_CHAR_DoubleQuote)
   ; ASCII-34 = ", ASCII-39 = '
    
   ProcedureReturn Chr(cQuote) + PeekS(@String$) + Chr(cQuote)
   ;ProcedureReturn Chr(cQuote) + String$ + Chr(cQuote)      
   EndProcedure
    
  Procedure.s _AddQuotes_(*String, cQuote.c=#STR_CHAR_DoubleQuote)  ; 
    ; ASCII-34 = ", ASCII-39 = '
    ProcedureReturn Chr(cQuote) + PeekS(*String) + Chr(cQuote)
  EndProcedure
  
  MyAddQuotes = @_AddQuotes_()    ; die Adresszuweisung im Modul und braucht _AddQuotes_ nicht mehr Public
EndModule

UseModule Quotes
Define s$, N, K, t_C, t_P, t_m

N = 100000  
s$ = "Ich bin ein String und war ein String"

t_C = ElapsedMilliseconds()
For K=0 To N
  res$ = AddQuotes_Classic(s$)
Next
t_C = ElapsedMilliseconds()-t_C
Debug "Classic : " + t_C + "ms"
Debug res$
Debug ""

t_P = ElapsedMilliseconds()
For K=0 To N
  res$ =  MyAddQuotes(s$)
Next
t_P = ElapsedMilliseconds()-t_P
Debug "Prototype : " + t_P + "ms"
Debug res$
Debug ""


MessageRequester("Ergebnis", "Classic : " + t_C + "ms" + #CRLF$ + "Prototype : " + t_P )

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: ReplaceString(), FindString() unschlagbar?

Beitrag von NicTheQuick »

Axolotl hat geschrieben: 18.11.2022 18:39

Code: Alles auswählen

Define AddQuotes.AddQuotes = @_AddQuotes_()
Ich habe da mal eine Frage: Kann man die Procedure so auch in anderen Proceduren benutzen?
Ich verwende eigentlich immer Global oder Protected und Define dann in Verbindung mit Shared.
Na klar, nutz einfach "Global" statt "Define". Dann verhält es sich im Grunde wie eine echte Procedure.
Bild
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: ReplaceString(), FindString() unschlagbar?

Beitrag von SMaag »

Na klar, nutz einfach "Global" statt "Define". Dann verhält es sich im Grunde wie eine echte Procedure.
Da muss man erst mal drauf kommen. Aber klar, wenn Define geht, dann muss auch Global funktionieren.
Hatte gerade das Problem, dass wenn man im Declare-Teil die Protypes mit Define verwendet, dann
sind sie trotz UseModul nicht nutzbar - Der Compiler bringt fehler.

Stellt man dann trotz UseModul noch den Modulnamen:: vor, dann geht's!
mit Global ist das nicht mehr nötig und es reicht UseModule
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: ReplaceString(), FindString() unschlagbar?

Beitrag von SMaag »

Hier die Demo, damit man das mit Define und Global Testen kann.
Das Ergebnis! Immer Global verwenden, dann funktioniert das wie man erwartet!
Mit Define muss man innerhalb von Proceduren trotzdem noch Modul:: vorstellen.

Code: Alles auswählen


DeclareModule STR
  Prototype.i ReplaceChar(String$, cSearch.c, cReplace.c) ; ProtoType-Function for ReplaceChar
  Global ReplaceChar.ReplaceChar                 ; define Prototype-Handler for CountChar
  ;Define ReplaceChar.ReplaceChar                 ; define Prototype-Handler for CountChar

  #STR_CharSize=2
EndDeclareModule

Module STR

 Procedure.i _ReplaceChar(*String, cSearch.c, cReplace.c)
  ; ============================================================================
  ; NAME: _ReplaceChar
  ; DESC: !PointerVersion! use it as ProtoType ReplaceChar()
  ; DESC: Replace a Character in a String with an other Character
  ; DESC: To replace all ',' with a '.' use : ReplaceChar(@MyString, ',', '.')
  ; DESC: This a replacement for ReplaceString() only for a single Char
  ; DESC: and with direct *String Access. This is 2-3 tiems faster than
  ; DESC: ReplaceString().
  ; DESC: To UCase a single char use ReplaceChar(MyString, 'e', 'E')
  ; VAR(String$) : The String
  ; VAR(cSearch) : Character to search for and replace
  ; VAR(cReplace): the Replace Charcter (new Character)
  ; VAR(*RetVal_NoOfChars.Integer): Place here a Pointer to a PB Integer-Struct
  ;                               to get back the NoOfCharsFound/Replaced
  ; RET.s : The new String
  ; ============================================================================
    Protected *char.Character   ; Pointer to a virutal Char-Struct
    Protected N
    
    *char = *String         
    If *char    
      While *char\c               ; until end of String
        If *char\c =  cSearch
          *char\c = cReplace    ; replace the Char
          N + 1
        EndIf
        *char + #STR_CharSize   ; Index to next Char
      Wend
    EndIf
    ProcedureReturn N
  EndProcedure
  ReplaceChar = @_ReplaceChar()     ; Bind ProcedureAdress to the PrototypeHandler
  
EndModule


UseModule STR
EnableExplicit 

Procedure ShowIt()
  Define s$ = "Hallo Hallo"
  Define N
  Debug s$
  N = ReplaceChar(s$,'a', 'e')          ; mit Golbal ReplaceChar.ReplaceChar ; geht das immer
  ; N = STR::ReplaceChar(s$,'a', 'e')   ; mit Define ReplaceChar.ReplaceChar ; muss Modul vorgestellt werden
  Debug "Ersetzungen = " + N + " : " + s$
  
  N = ReplaceChar(s$,'H', 'B')
  Debug "Ersetzungen = " + N + " : " + s$
EndProcedure

ShowIt()
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: ReplaceString(), FindString() unschlagbar?

Beitrag von NicTheQuick »

Das war mir jetzt wiederum nicht bewusst. Gut zu wissen. :allright:
Bild
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: ReplaceString(), FindString() unschlagbar?

Beitrag von mk-soft »

Allgemein:
Variablen innerhalb von Prozeduren mit Protected deklarieren (Nicht mit Define).
Variablen mit Define sind für MainScope und kann mit Shared in der Prozedur bekannt gemacht werden.
Variablen mit Global sind überall sichtbar

Bei Verwendung Modulen müssen Variablen die öffentlich sind in DeclareModule deklariert werden.
Es gelten aber die gleichen Regeln im wie bei Allgemein.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Axolotl
Beiträge: 146
Registriert: 31.12.2008 16:34

Re: ReplaceString(), FindString() unschlagbar?

Beitrag von Axolotl »

:allright:
Ich benutze die Kombi Define und Shared gerne für (wie ich sie nenne Semiglobale Variablen).
Wenn eine Variable für die Verwendung innerhalb einer Prozedure durch Shared "freigegeben" werden muss gehört das für mich zu meiner Art der defensiven Programmierung.

Kleine Anmerkung zur u.g. Code-Zeile: :oops:
Die Zwei ist bei UNICODE richtig, bei ASCII wäre hier eine Eins richtig.
Hilfreich für Anwender von älteren PB-Compilern, denn seit einigen Versionen wird nur noch UNICODE unterstützt.

Code: Alles auswählen

#STR_CharSize=2    ; <--> #STR_CharSize=SizeOf(CHARACTER) 
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: ReplaceString(), FindString() unschlagbar?

Beitrag von mk-soft »

SizeOf(CHARACTER) ist eine Compiler Funktion und trägt beim kompilieren den Wert ein.
Also im Programm direkt verwenden ohne Zwischenvariable.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benubi
Beiträge: 186
Registriert: 22.10.2004 17:51
Wohnort: Berlin, Wedding

Re: ReplaceString(), FindString() unschlagbar?

Beitrag von Benubi »

Es lassen sich auch bei Modulen Variablen im Module/EndModule (also außerhalb von DeclareModule) definieren, aber dann sind diese quasi nur für das Modul intern sichtbar, und nicht mehr über das Module:: Prefix erreichbar. Hier sollte man aber auch direkt in den ersten Zeilen seine Variablen deklarieren, weil das durchaus auf den Scope Einfluß hat.

Daher mit dem Prefix kommt man nur an die Shared und Global Variabeln in Declare Teil, man kann aber auch welche im Module-Teil verstecken. Und ich denke Macros kann man auch direkt in den Declare Teil reintun, sonst ginge es eh nicht. Aber selbst bei einem UseModule sollten diese im Module Teil deklarierten Variablen privat bleiben.

Zum Modul Namespace gab es auch manchmal Problemchen innerhalb von Modulen, glaube ich, wenn man Variablen mehrfach deklariert in einer Prozedur dann kann der Kompiler es machmal nicht mitbekommen und es gibt Heisenbugs. Ich glaube aber das wurde gefixt und in der neueren Version gab es dann eine Fehlermeldung (bereits deklariert). Man sollte also dennoch immer ein wenig die Möglichkeit von Namens-Konflikten im Auge behalten. Es scheint jetzt aber ordentlich gehändelt zu werden:

Code: Alles auswählen

DeclareModule abc
  ; Kommentare einfügen oder entfernen um mit UseModule zu testen
  ; Global hallo_welt = 10
  Declare GetHallo()
EndDeclareModule

Module abc
  Global hallo_welt = 123
  
  Procedure GetHallo()
    ProcedureReturn hallo_welt
  EndProcedure
  
EndModule

;Debug abc::hallo_welt
Debug abc::GetHallo()
UseModule abc
Debug hallo_welt
Debug GetHallo()
Das ist dann schneller als Shared zu implementieren auf die Art, aber ich weiß nicht ob es sich um die gleichen Speicher-Arten handelt welche verwendet werden, also ob globaler Speicher hier verwendet wird und sich das uU auf die Programmgeschwindigkeit negativ auswirken könnte, wie PB das intern händelt.
Antworten