Seite 1 von 1

Erweiterte Trim-Funktionen

Verfasst: 02.02.2005 22:54
von Kekskiller
Hab für meine paar kleinen Scriptfummeleien eine/zwei erweiterte
Trimfunktion/en geschrieben, sie ermöglichen einem das Wegkürzen
von Leerzeichen rechts ung links. Der String wird direkt per Adresse
manipuliert, teils sehr nützlich:

Code: Alles auswählen

 ;/ schneidet links alle leerzeichen ab
Procedure.s TrimLeft(*sourcestring)
  Protected z
  Protected str$
  str$ = PeekS(*sourcestring)
  For z = 1 To Len(str$)
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen
      Break
    EndIf
  Next
  If z = Len(str$)
    z = 1
  EndIf
  PokeS(*sourcestring, Right(str$, Len(str$) - z + 1))
EndProcedure

;/ schneidet rechts alle leerzeichen ab
Procedure.s TrimRight(*sourcestring)
  Protected z
  Protected str$
  str$ = PeekS(*sourcestring)
  For z = 1 To Len(str$)
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen
      Break
    EndIf
  Next
  If z = Len(PeekS(str$))
    z = 1
  EndIf
  PokeS(*sourcestring, Left(str$, Len(str$) - z + 1))
EndProcedure

Verfasst: 02.02.2005 23:48
von Andre
Ich habe mal versucht, dafür noch ein Beispiel zu ergänzen:

Code: Alles auswählen

 ;/ schneidet links alle leerzeichen ab 
Procedure.s TrimLeft(*sourcestring) 
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(str$) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Right(str$, Len(str$) - z + 1)) 
EndProcedure 

;/ schneidet rechts alle leerzeichen ab 
Procedure.s TrimRight(*sourcestring) 
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(PeekS(str$)) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Left(str$, Len(str$) - z + 1)) 
EndProcedure

;- Example
a$ = "    Test-String        "
Debug a$ + "|"

TrimLeft(@a$) 
Debug a$ + "|"


TrimRight(@a$)
Debug a$ + "|"
Irgendwie fände ich es aber doch besser, wenn die Prozeduren mit Rückgabewerten arbeiten würden. Oder worin liegt der besondere Anwendungszweck, übergebene Strings direkt zu manipulieren ?

Verfasst: 03.02.2005 00:08
von Danilo
Andre hat geschrieben:Irgendwie fände ich es aber doch besser, wenn die Prozeduren mit Rückgabewerten arbeiten würden.
Dann könntest Du ja gleich RTrim() und LTrim() nehmen.

Ich weiß auch nicht was an diesem Prozeduren "erweitert"
sein soll. Sind bloß beide sehr ineffizient (PeekS+Trim+Left/Right+PokeS).

Verfasst: 03.02.2005 01:22
von Kristel
Hab deine Version ein ganz klein wenig überarbeitet.
Dann habe ich die Zeit der beiden Proceduren für Andre's
Beispiel genommen und siehe da: den konstanten Wert
von Len(str$) in len zu speichern bringt etwas.

Hier der Code:

Code: Alles auswählen

#Durchlaeufe = 100000

Procedure.s TrimLeft(*sourcestring) ; Originalfassung
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(str$) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Right(str$, Len(str$) - z + 1)) 
EndProcedure 

Procedure.s TrimRight(*sourcestring) ; Originalfassung
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(PeekS(str$)) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Left(str$, Len(str$) - z + 1)) 
EndProcedure 

Procedure.s TrimLeft_K(*sourcestring) ; von Kristel überarbeitete Fassung 
  Protected z 
  Protected str$
  Protected len.l
  str$ = PeekS(*sourcestring)
  len = Len(str$)
  For z = 1 To len 
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = len 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Right(str$, len - z + 1)) 
EndProcedure 

Procedure.s TrimRight_K(*sourcestring) ; von Kristel überarbeitete Fassung
  Protected z 
  Protected str$
  Protected len.l
  str$ = PeekS(*sourcestring)
  len = Len(str$)
  For z = 1 To len 
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = len 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Left(str$, len - z + 1)) 
EndProcedure 

zeit1 = GetTickCount_()

For x = 1 To #Durchlaeufe
  a$ = "    Test-String        "
  TrimLeft(@a$)
  TrimRight(@a$)
Next  

zeit1 = GetTickCount_() - zeit1

Delay(100)

zeit2 = GetTickCount_()

For x = 1 To #Durchlaeufe
  a$ = "    Test-String        "
  TrimLeft_K(@a$)
  TrimRight_K(@a$)
Next  

zeit2 = GetTickCount_() - zeit2

MessageRequester("Ergebnis","Kekskiller: "+Str(zeit1)+" ms"+Chr(13)+Chr(10)+"Kristel: "+Str(zeit2)+" ms")
Bei 1 Million Durchläufe ergibt sich folgendes Resultat:
Kekskiller: 5531 ms
Kristel: 4343 ms
Original: 922 ms (unter gleichen Bedingungen getestet)

Wenn du schon versuchs RTrim()/LTrim() nach zubauen,
dann wenigstens mit maximalem Speed bei einiger maßen
Codeverständlichkeit. :wink:

Verfasst: 03.02.2005 20:16
von Kekskiller
Ooops :oops: ...
Ich Idiot hab dpch glatt die Standartfunktionen in der Hilfe übersehen :| ...
Entschuldigt bitte, das hab ich nicht gesehen...

*HÜST*

der eigentliche Sinn darin war, die Funktionen aus einer Dll heraus zu nutzen,
da ich meinen Scriptinterpreter in eine Dll stecken wollte, dort sich aber nur
blanke Werte übergeben ließen, wie eben eine Adresse.

Nunja, ähä... (was für eine Schande...)