Seite 1 von 2

Trim() / LTrim() usw.

Verfasst: 18.02.2006 21:01
von Batze
Warum gibt es bei Trim() und co eigentlich keinen optionalen Parameter, mit dem man bestimmen kann welches Zeichen entfernt wird.

Verfasst: 19.02.2006 11:58
von Pelagio
@Batze
Wozu???
Es gibt doch den Stringbefehl

Code: Alles auswählen

RemoveString(String$,  LöschString$ [, Modus])
Dieser Befehl ermittelt alle Vorkommen des 'LöschString$' im angegebenen 'String$' und entfernt diese, lt. PB Help.
:allright:

Verfasst: 19.02.2006 12:05
von Jake
Das ist nicht das was Batze meint.
Trim entfernt nur vom Anfang und vom Ende des Strings und RemoveString im gesammten String.

Verfasst: 19.02.2006 12:18
von ts-soft
Das was Batze gemeint hat, wann ist das Sinnvoll?

Sicherlich kann man sowas irgendwann einmal gebrauchen, aber doch Wohl
sehr selten. Meiner Meinung nach also überflüssig.

Verfasst: 19.02.2006 12:39
von Pelagio
:allright: Ich gebe ts-Soft recht und sehe es auch so.

Aber falls Batze diese Funktion in irgendeinem Source benötigt hier eine entsprechende Funktion:

Code: Alles auswählen

Procedure.s zTrim(Value.s, Char.s)
  Repeat
    If (Left(Value,1)=Char): Value = Mid(Value,2, Len(Value)): Else: Break: EndIf
  ForEver
  Repeat
    If (Right(Value,1)=Char): Value = Left(Value,Len(Value)-1): Else: Break: EndIf
  ForEver
  ProcedureReturn Value
EndProcedure

Debug zTrim("---Hallo---", "-")
:allright:

Verfasst: 19.02.2006 13:21
von Batze
Gut Frage beantwortet: Gibts nicht weils niemand braucht. :lol:

Verfasst: 19.02.2006 15:33
von Froggerprogger
Hier noch eine etwa 10-mal schnellere Version für diese Funktion. Der Speed-Contest ist eröffnet.

Code: Alles auswählen

Procedure.s zTrim(Value.s, Char.s)   ; "Originalversion"
  Repeat 
    If (Left(Value,1)=Char): Value = Mid(Value,2, Len(Value)): Else: Break: EndIf 
  ForEver 
  Repeat 
    If (Right(Value,1)=Char): Value = Left(Value,Len(Value)-1): Else: Break: EndIf 
  ForEver 
  ProcedureReturn Value 
EndProcedure 

Procedure.s TrimEx(Value.s, Char.s)   ; "Speed-Up-Version"
  Protected *c.BYTE, *vs.BYTE, *ve.BYTE, len.l
  
  len = Len(Value)
  If len = 0
    ProcedureReturn ""
  Endif
  
  *c = @Char
  *vs = @Value
  *ve = @Value + len - 1
  
  While *vs\b = *c\b
    *vs + 1
  Wend
  
  While *ve\b = *c\b
    *ve - 1
  Wend 
  
  ProcedureReturn PeekS(*vs, *ve - *vs + 1)
EndProcedure

#max = 100000
time = ElapsedMilliseconds()
For i = 0 to #max
  zTrim("-----------Hallo----------", "-")
Next  
time1 = ElapsedMilliseconds() - time
time = ElapsedMilliseconds()
For i = 0 to #max
  TrimEx("-----------Hallo----------", "-")
Next  
time2 = ElapsedMilliseconds() - time

MessageRequester("", "Zeiten: " + Str(time1) + "  " + Str(time2))

Verfasst: 20.02.2006 00:09
von Deeem2031
Wie du willst:

Code: Alles auswählen

Procedure.s zTrim(Value.s, Char.s)   ; "Originalversion" 
  Repeat 
    If (Left(Value,1)=Char): Value = Mid(Value,2, Len(Value)): Else: Break: EndIf 
  ForEver 
  Repeat 
    If (Right(Value,1)=Char): Value = Left(Value,Len(Value)-1): Else: Break: EndIf 
  ForEver 
  ProcedureReturn Value 
EndProcedure 

Procedure.s TrimEx(Value.s, Char.s)   ; "Speed-Up-Version" 
  Protected *c.BYTE, *vs.BYTE, *ve.BYTE, len.l 
  
  len = Len(Value) 
  If len = 0 
    ProcedureReturn "" 
  EndIf 
  
  *c = @Char 
  *vs = @Value 
  *ve = @Value + len - 1 
  
  While *vs\b = *c\b 
    *vs + 1 
  Wend 
  
  While *ve\b = *c\b 
    *ve - 1 
  Wend 
  
  ProcedureReturn PeekS(*vs, *ve - *vs + 1) 
EndProcedure 

Procedure.s DTrimEx(Value.s, Char.s)   ; "Deeem2031s ultimative Speed-Up-Version :D" 
  Protected *vs.BYTE, *ve.BYTE, len.l 
  
  !Mov Eax, dword[p.v_Value]
  !Call l_strlen
  !MOV dword[p.v_len], Eax
  
  If len
    *vs = @Value 
    *ve = @Value + len - 1 
  
    !Mov Edx, dword[p.v_Char]
    !Mov dl, byte[Edx]
    !Mov Eax, dword[p.p_vs]
    asm_loop1_start:
    !Cmp byte[Eax], dl
    !Jne l_asm_loop1_end
    !Inc Eax
    !Cmp byte[Eax], dl
    !Jne l_asm_loop1_end
    !Inc Eax
    !Cmp byte[Eax], dl
    !Jne l_asm_loop1_end
    !Inc Eax
    !Cmp byte[Eax], dl
    !Jne l_asm_loop1_end
    !Inc Eax
    !Jmp l_asm_loop1_start
    asm_loop1_end:
    !Mov dword[p.p_vs], Eax
    
    !Mov Eax, dword[p.p_ve]
    asm_loop2_start:
    !Cmp byte[Eax], dl
    !Jne l_asm_loop2_end
    !Dec Eax
    !Cmp byte[Eax], dl
    !Jne l_asm_loop2_end
    !Dec Eax
    !Cmp byte[Eax], dl
    !Jne l_asm_loop2_end
    !Dec Eax
    !Cmp byte[Eax], dl
    !Jne l_asm_loop2_end
    !Dec Eax
    !Jmp l_asm_loop2_start
    asm_loop2_end:
    !Mov dword[p.p_ve], Eax
    
    ProcedureReturn PeekS(*vs, *ve - *vs + 1) 
  EndIf 
  ProcedureReturn "" 
EndProcedure 

#max = 1000000 
;time = ElapsedMilliseconds() 
;For i = 0 To #max 
  ;zTrim("-----------Hallo----------", "-") 
;Next  
;time1 = ElapsedMilliseconds() - time 
time = ElapsedMilliseconds() 
For i = 0 To #max 
  TrimEx("-----------Hallo----------", "-") 
Next  
time2 = ElapsedMilliseconds() - time 
time = ElapsedMilliseconds() 
For i = 0 To #max 
  DTrimEx("-----------Hallo----------", "-") 
Next  
time3 = ElapsedMilliseconds() - time 
 

MessageRequester("", "Zeiten: " + Str(time2) + "  " + Str(time3))

DataSection
Data.b $31 ,$C0 ,$C3 ,$B8 ,$01 ,$00 ,$00 ,$00 ,$C3 ,$B8 ,$02 ,$00 ,$00 ,$00 ,$C3 ,$B8
Data.b $03 ,$00 ,$00 ,$00 ,$C3 ,$B8 ,$04 ,$00 ,$00 ,$00 ,$C3 ,$B8 ,$05 ,$00 ,$00 ,$00
Data.b $C3 ,$B8 ,$06 ,$00 ,$00 ,$00 ,$C3 ,$B8 ,$07 ,$00 ,$00 ,$00 ,$C3
StrLen:
Data.b $80 ,$38 ,$00 ,$74 ,$CE ,$80 ,$78 ,$01 ,$00 ,$74 ,$CB ,$80 ,$78 ,$02 ,$00 ,$74
Data.b $CB ,$80 ,$78 ,$03 ,$00 ,$74 ,$CB ,$80 ,$78 ,$04 ,$00 ,$74 ,$CB ,$80 ,$78 ,$05
Data.b $00 ,$74 ,$CB ,$80 ,$78 ,$06 ,$00 ,$74 ,$CB ,$80 ,$78 ,$07 ,$00 ,$74 ,$CB ,$31
Data.b $D2 ,$42 ,$80 ,$3C ,$D0 ,$00 ,$74 ,$39 ,$80 ,$7C ,$D0 ,$01 ,$00 ,$74 ,$3A ,$80
Data.b $7C ,$D0 ,$02 ,$00 ,$74 ,$3B ,$80 ,$7C ,$D0 ,$03 ,$00 ,$74 ,$3C ,$80 ,$7C ,$D0
Data.b $04 ,$00 ,$74 ,$3D ,$80 ,$7C ,$D0 ,$05 ,$00 ,$74 ,$3E ,$80 ,$7C ,$D0 ,$06 ,$00
Data.b $74 ,$3F ,$80 ,$7C ,$D0 ,$07 ,$00 ,$75 ,$C8 ,$8D ,$04 ,$D5 ,$07 ,$00 ,$00 ,$00
Data.b $C3 ,$8D ,$04 ,$D5 ,$00 ,$00 ,$00 ,$00 ,$C3 ,$8D ,$04 ,$D5 ,$01 ,$00 ,$00 ,$00
Data.b $C3 ,$8D ,$04 ,$D5 ,$02 ,$00 ,$00 ,$00 ,$C3 ,$8D ,$04 ,$D5 ,$03 ,$00 ,$00 ,$00
Data.b $C3 ,$8D ,$04 ,$D5 ,$04 ,$00 ,$00 ,$00 ,$C3 ,$8D ,$04 ,$D5 ,$05 ,$00 ,$00 ,$00
Data.b $C3 ,$8D ,$04 ,$D5 ,$06 ,$00 ,$00 ,$00 ,$C3
EndDataSection
Na wer traut sich noch? :mrgreen:

Verfasst: 20.02.2006 00:16
von Hellhound66
Offtopic Frage:

Ist ein cmp byte ptr[EAX],dl schneller, als wenn ich ein DWord auslese und die einzelnen byte innerhalb eines Registers vergleiche?

mov EBX,dword ptr[EAX]
cmp bl,dl
jne @blubb
cmp bh,dl
jne @blubb
...

Verfasst: 20.02.2006 00:20
von Deeem2031
Wahrscheinlich nicht, allerdings wird der Pointer in Eax ja nach der Schleife gebraucht, also muss da sowieso ein "Inc Eax" stehen. Man könnte natürlich mehrere Schleifenende deklarieren, auf die Idee bin ich auch gekommen, aber ich wollte es ja nicht zu kompliziert machen.
Btw. Das ganze lässt sich noch optimieren. Also nich vom Asm-technischen her, sondern durch logisches Denken. Also ihr könnts noch besser schaffen ;)