How we split a string in to Pieces for general purpose string operations
here is a vb example i want to make asm convertion for that . How do i do so?
Private Sub Form_Load()
Dim FullString As String
Dim MainSetting() As String
Dim SubSetting1() As String
Dim SubSetting2() As String
FullString = "MainSetting1<>M1_SubSetting1<>M1_SubSetting2{}MainSetting2<>M2_SubSetting1<>M2_SubSetting2"
MainSetting = Split(FullString, "{}")
SubSetting1 = Split(MainSetting(0), "<>")
SubSetting2 = Split(MainSetting(1), "<>")
MsgBox MainSetting(0)
For i = 0 To UBound(SubSetting1)
MsgBox SubSetting1(i)
Next
MsgBox MainSetting(1)
For i = 0 To UBound(SubSetting2)
MsgBox SubSetting2(i)
Next
End Sub
what it does "MainSetting1<>M1_SubSetting1<>M1_SubSetting2{}MainSetting2<>M2_SubSetting1<>M2_SubSetting2"
is the main string
1- first it splits it in the array MainSetting (n) ; n are the number of string it finds
2- MainSetting1(0) t splits in the array SubSetting1(n) ; n are the number of string it finds
3- MainSetting1(1) t splits in the array SubSetting1(n) ; n are the number of string it finds
4- Finally display resulted setting in the message
Now how do we convert this in the asm code.Is there any macro to do split operations using delimiter.eg."{}"or "<>" or any one which we want to use.
kyo,
What are the forms of the input string and what form must the individual outputs be. I don't have a dialect of basic handy that has the "split" function so I don't know what its supposed to look like.
Input is the simple string.(does not matters what ever it is) Split divides the string where it finds delimiter.eg."{}"or "<>" or " " or "&" * or any one which we want to use.removes the delimiter and copies the parts to the MainString(n)= the parts of the splited strings. Out put is in the same form as the input is. The example i gave is fully working in the vb6 copy it to the form code and run it you will see the results.
What it does is takes a string and splits it into an array where it finds the specified delimiter. For exaple if i had the string "This is a test" and used the split function with the delimiter being char(32) which i believe is the space then i would have the following
string[0] = This
string[1] = is
string[2] = a
string[3] = test
the vb code would actually be string = split("This is a test", chr(32)) or something close... been awhile since i used vb as i found masm to be much better and i like the speed and not needed to have the extra runtime files and such.
here is a vc++ function i wrote that does close to the same thing as he wants.
void CJIrcView::GetColor(LPCTSTR itmName)
{
CString Path(*__argv);
int i = Path.ReverseFind('\\') + 1;
if(i) Path = Path.Left(i);
vm_strINIFile = Path + _T("JClient.ini");
vm_strSectionName = _T("COLOURS");
GetPrivateProfileString((LPCTSTR)vm_strSectionName,(LPCTSTR)itmName, "0,0,0;", vm_lRetValue, 255, (LPCTSTR)vm_strINIFile);
const char delimiters[] = ",;";
char *token;
token = strtok (vm_lRetValue, delimiters);
vm_RedCode = atoi(token);
token = strtok (NULL, delimiters);
vm_GreenCode = atoi(token);
token = strtok (NULL, delimiters);
vm_BlueCode = atoi(token);
}
Hello,
If I understand well the split function take the string between to delimiters and make a concatenation of the strings Found ?.
That's not very difficult to simulate with standard asm,perhaps the MID function is missing in masm32 but i am not sure.
ToutEnMasm
Best guess at the moment gets something like this.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
bcopy PROTO :DWORD,:DWORD
.data?
value dd ?
.data
item db "MainSetting1 SubSetting11 SubSetting12",13,10
db "MainSetting2 SubSetting21 SubSetting22",13,10
db "MainSetting3 SubSetting31 SubSetting32",13,10
db "MainSetting4 SubSetting41 SubSetting42",13,10
db "MainSetting5 SubSetting51 SubSetting52",13,10
db "MainSetting6 SubSetting61 SubSetting62",13,10
db "MainSetting7 SubSetting71 SubSetting72",13,10
db "MainSetting8 SubSetting81 SubSetting82",0
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
call main
inkey
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
LOCAL array1 :DWORD
LOCAL cnt1 :DWORD
LOCAL array2 :DWORD
LOCAL npos :DWORD
LOCAL pbuf :DWORD
LOCAL pbuf1 :DWORD
LOCAL buffer[128]:BYTE
LOCAL buffer1[128]:BYTE
push esi
push edi
mov cnt1, rv(ltok,OFFSET item,ADDR array1)
mov esi, array1
sub esi, 4
@@:
add esi, 4
mov pbuf, ptr$(buffer)
invoke bcopy,[esi],pbuf
print pbuf,13,10
mov npos, 0
mov pbuf1, ptr$(buffer1)
mov npos, rv(ArgByNumber,pbuf,pbuf1,1,npos)
print "arg1 = "
print pbuf1,13,10
mov pbuf1, ptr$(buffer1)
mov npos, rv(ArgByNumber,pbuf,pbuf1,1,npos)
print "arg2 = "
print pbuf1,13,10
mov pbuf1, ptr$(buffer1)
mov npos, rv(ArgByNumber,pbuf,pbuf1,1,npos)
print "arg3 = "
print pbuf1,13,10,13,10
sub cnt1, 1
jnz @B
free array1
free array2
pop edi
pop esi
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
bcopy proc src:DWORD,dst:DWORD
push ebx
mov eax, src
mov ecx, dst
xor edx, edx
@@:
mov bl, [eax+edx]
mov [ecx+edx], bl
add edx, 1
test bl, bl
jnz @B
pop ebx
ret
bcopy endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Which delivers this output.
MainSetting1 SubSetting11 SubSetting12
arg1 = MainSetting1
arg2 = SubSetting11
arg3 = SubSetting12
MainSetting2 SubSetting21 SubSetting22
arg1 = MainSetting2
arg2 = SubSetting21
arg3 = SubSetting22
MainSetting3 SubSetting31 SubSetting32
arg1 = MainSetting3
arg2 = SubSetting31
arg3 = SubSetting32
MainSetting4 SubSetting41 SubSetting42
arg1 = MainSetting4
arg2 = SubSetting41
arg3 = SubSetting42
MainSetting5 SubSetting51 SubSetting52
arg1 = MainSetting5
arg2 = SubSetting51
arg3 = SubSetting52
MainSetting6 SubSetting61 SubSetting62
arg1 = MainSetting6
arg2 = SubSetting61
arg3 = SubSetting62
MainSetting7 SubSetting71 SubSetting72
arg1 = MainSetting7
arg2 = SubSetting71
arg3 = SubSetting72
MainSetting8 SubSetting81 SubSetting82
arg1 = MainSetting8
arg2 = SubSetting81
arg3 = SubSetting82
Press any key to continue ...
hutch--
Split and join are 2 very important functions and you should include them in the high level string macros. I just checked the help of high level left$ and righ$ macros are there but mid$ is also missing.
You should also make Split$ Join$ and Mid$ macros. These perform very important tasks.
Join does the reverse of split it adds all arrays to a string with the delimiter supplied.
string[0] = This
string[1] = is
string[2] = a
string[3] = test
rslt = Join(string()," ")
rslt =This is a test ; ans would be like that
kyo,
There is a mid procedure in the masm32 library.
szMid proc source:DWORD, substring:DWORD, stPos:DWORD, ln:DWORD
VB emulation is not exactly what you are after as its architecture has it has a different set of assumptions. The macros handle the easy stuff with no problems but where speed matters, there are faster ways of doing most of this stuff.
In the masm32 subforum is a posting that has two (2) very high speed tokenisers, one for lines and one for seperate words. The example I posted used the line tokeniser and a sequential word parser "ArgByNumber".
If you are committed to VB style string arrays, you are probably stuck with VB style performance but if you need improved performance, you will need to think of the layout in a different way.
Hello,
join is made,with no limits in number and size of strings.Just limit by the size of memory.
WriteToMemHeap is a function tha i have posted here
Give me a real string to split and i make the function split.
.data
string db "This",0 ;asciiz
db "is",0
db "a",0
db "test",0
db 0 ;end list
memheap MEMHEAP <>
separetor db " ",0
.code
;@@@@@@@@@@@@@@@@@@@@@@@ POINT d'ENTREE du code, start: @@@@@@@@@@@@@@@@@@@@@@
start:
invoke join,addr string,addr separetor,addr memheap
;affiche
;free memory
.if dword ptr memheap.Pheap != 0 ;&& eax != 0
invoke MessageBox,NULL,memheap.Pheap,SADR("Titre"),MB_OK
invoke WriteToMemHeap,addr memheap,NULL,NULL
.endif
invoke ExitProcess,0
;@@@@@@@@@@@@@@@@@@@@@@@ POINT de sortie du code @@@@@@@@@@@@@@@@@@@@@@@
;################################################################
join PROC uses esi edi ebx pstrings:DWORD,pseparetor:DWORD,pheap:DWORD
local phrase[MAX_PATH+1]:BYTE
Local retour:DWORD
mov retour,0
mov esi,pstrings
@@:
.if byte ptr [esi] != 0
invoke lstrcpy,addr phrase,esi
invoke lstrcat,addr phrase,pseparetor
invoke WriteToMemHeap,pheap,addr phrase,NULL
.if eax != 0
mov retour,1
;success,is another ?
mov edi,esi
mov ecx,MAX_PATH
mov al,0
cld
repnz scasb
;edi pointer on the new string
mov esi,edi
jmp @B
.else
;failed
mov ebx,pheap
.if dword ptr [ebx][MEMHEAP.Pheap] != 0
;free memory
invoke WriteToMemHeap,pheap,NULL,NULL
.endif
mov retour,0
.endif
.endif
Findejoin:
mov eax,retour
ret
join endp
ToutEnMasm
:bg good if it works but it gives error to me which lib in have to inlude for WriteToMemHeap api.
to split you can use same string "This is a test" and use " " space as delimiter , get it back
This,0
is,0
a,0
test,0
and a question what happens if its binary i mean 0 is in the text or input or string in case bin operation.
Hello,
It's work with no problems.
To have the function WriteToMemHeap follow this link,it's here.
http://www.masm32.com/board/index.php?topic=2253.msg17776#msg17776
If you want to put the NULL caracter as separator,modify a little the function.
original code
.if byte ptr [esi] != 0
invoke lstrcpy,addr phrase,esi
invoke lstrcat,addr phrase,pseparetor
invoke WriteToMemHeap,pheap,addr phrase,NULL
new code
.if byte ptr [esi] != 0
invoke lstrcpy,addr phrase,esi
mov ebx,pseparetor
.if byte ptr [ebx] != 0
invoke lstrcat,addr phrase,pseparetor
.endif
invoke WriteToMemHeap,pheap,addr phrase,NULL
in data write
.data
separetor db 0,0
For the list of strings,you must terminate the list by a zero,there is no other choice.
ToutEnMasm