Procedure.l SplitStringByChar(StringToSplit.s, SplitChar.s, ArrayPtr.l)
; free the current array
! mov edx,[esp+8]
! call PB_FreeArray
; duplicate the string to split
! mov edx,[esp]
! lea ecx,[esp+8]
! call SYS_FastAllocateString
; replace all splitchars by 0 and push all pointers to the substrings
! mov edx,[esp+4]
! mov ah,byte [edx]
! xor ecx,ecx
! mov edx,[esp+8]
! _splitstring_loop0:
! inc ecx
! push edx
! _splitstring_loop1:
! mov al,byte [edx]
! inc edx
! And al,al
! jz _splitstring_cont
! cmp al,ah
! jne _splitstring_loop1
! mov byte [edx-1],0
! jmp _splitstring_loop0
; correct stack if array allocation failed
! _ss_arrayfailed:
! pop ecx
! sal ecx,2
! add esp,ecx
! jmp _ss_exit
; allocate new array
! _splitstring_cont:
! push ecx
! mov ebx,ecx
! mov eax,4
! call PB_AllocateArray
! jz _ss_arrayfailed
! mov dword [eax],8
! pop ecx
! mov edx,ecx
! sal edx,2
! add edx,eax
! add eax,4
; set all pointers
! _splitstring_loop2:
! popd [edx]
! sub edx,4
! loop _splitstring_loop2
! _ss_exit:
ProcedureReturn
EndProcedure
; test the procedure
Dim B.s(0)
; supplying two times B() is required to free the old array
B() = SplitStringByChar("Hello, this is a test to see if the splitting of this string will be correct"," ",B())
ArrayLength = PeekL(@B()-8)
For i=0 To ArrayLength-1
Debug B(i)
Next
Procedure.l SplitStringByChar(StringToSplit.l, SplitChar.s, ArrayPtr.l)
EnableASM
; replace all split chars by 0
MOV edx,[p.v_SplitChar]
MOV ecx,[p.v_ArrayPtr]
MOV bh,byte [edx]
XOR eax,eax
MOV edx,[p.v_StringToSplit]
MOV dword [ecx],edx
ADD ecx,4
! _splitstring_loop0:
MOV bl,byte [edx]
CMP bl,0
JZ _fin
INC edx
CompilerIf #PB_Compiler_Unicode
INC edx
CompilerEndIf
XOR bl,bh
JNZ _splitstring_loop0
CompilerIf #PB_Compiler_Unicode
MOV byte [edx-2],0
CompilerElse
MOV byte [edx-1],0
CompilerEndIf
INC eax
MOV dword [ecx],edx
ADD ecx,4
JMP _splitstring_loop0
! _fin:
DisableASM
ProcedureReturn
EndProcedure
Dim b.s(30) ;half the len of your string
nb=SplitStringByChar(@"Hello, this is a test to see if the splitting of this string will be correct"," ",B())
ReDim b(nb)
For i=0 To nb
Debug b(i)
Next i
This is not bulletproof and highly risky.
You have to dim your area in order it's larger than the number of split you will do. (at most half the number of letters in your string)
I have no idea how fast it is.
Last edited by Fig on Sat Jun 24, 2017 5:07 pm, edited 4 times in total.
There are 2 methods to program bugless.
But only the third works fine.
You should test your Split function with a separator with more than one character and when the first char of the sep matches.
Example: StringToSplit = "ABCxzDEFxyGHI", Separator = "xy"