Hello.
I am having troubles learning how to manipulate strings using masm32.
What I want to do is get some input from the console, which i can do rather easily.
I then want to take the input string and break it into is seperate tokens. similar to what can be done with c's strtok function.
For example, I want to take the string
"this is a string that i want to break"
and create the following tokens.
this
is
a
string
etc. etc.
What i had initially thought about doing was to use the InString function, determine the first occurence of a space, then use szMid to copy the correnct number of characters into a new string variable. I would then proceed to the next occurence of a space and do the same.
This is the code that I have that does not work.
.data
buf db 00ffh dup(?) ;define array of 100 bytes for user input
buflen dd 0ffh ;Define max length of buffer
space db " ",0 ;space for tokenizing string
.code
start:
call main
print "Press any key to continue..."
;StdIn takes buffer:DWORD, buf length:DWORD
invoke StdIn, DWORD ptr[buf], buflen
exit
main proc
;input() is a macro for getting input from std input
mov DWORD ptr[buf], input("Enter the string:")
;InString returns location of substring in eax register
invoke InString , 1, DWORD ptr[buf], DWORD ptr[space]
print DWORD ptr[eax]
ret
main endp
end start
I would love some assistance with string manipulation
This is what i have been working on:
I know it does not work though.
LOCAL numBytes dd ;variable to store the number of bytes the token is
;input() is a macro for getting input from std input
mov DWORD ptr[buf], input("Enter the string:")
;InString returns location of substring in eax register
;InString start:DWORD, source:DWORD, substr:DWORD
invoke InString , 1, DWORD ptr[buf], DWORD ptr[space]
;eax now stores location of 1st space
;create new buffer for string
inc eax ;Incrememnt eax (final length of substr)
mov numBytes, eax ;Assign eax to numBytes
invoke Malloc, numBytes ;we wish for length + 1 bytes to store string.
;call szMid and pass in starting location and ending location
;szMid source:DWORD, dest:DWORD, startpos:DWORD, length:DWORD
invoke szMid, DWORD ptr[buf], DWORD ptr[eax], 1, numBytes
;store ptr to our new token on the stack.
push eax
It depends on how much work you want to do. You can use the library procedure StdIn to load text input into a buffer then use another library procedure "parse_line" to do what you are after tokenising the components of the input string. The procedures are in the MASM32 library and the documentation is in the help file for the MASM32 library on the help menu for QE.
I can't seem to find the parse_line procedure in any of the help files.
Select the masm32 lib help file. In the file select masm32 libraries.
At the and of the double list select "In Memory Text Read and Write"
Then select "parse_line" and you have the reference.
Ok, I'll look at that now. What I have done instead was begin work on the functions that i needed in order to start tokenizing.
I just finished the following function:
;returns -1 if not found, otherwise returns 0 based location of character in
;ECX
FindFirstOf proc
;esp + 12 = character to look for
;esp + 16 = dword ptr to address of string to search
;esp + 20 = length of string
LOCAL strlength :DWORD
mov eax, DWORD ptr[esp+20] ;move string length to eax
mov strlength, eax ;move length of string in eax to strlegnth
mov ecx, 0 ;we will use ECX to store our index
mov edx,DWORD PTR[esp+16] ;set edx to start of string
back:
cmp ecx, strlength ;test if we are at last char of string
je done ;if we are, we did not find character
mov al,BYTE PTR[EDX + ecx] ;move char at edx to al
cmp al,BYTE ptr[esp+12] ;esp is the character we want to look for.
je found ;if not same, go to start of loop
inc ecx ;set index to the next position in str
jmp back ;it was the same, so go to found
done:
mov ecx, -1 ;not found
found:
add esp, 20 ;balance stack
ret
FindFirstOf endp
Hutch-
QuoteAt the and of the double list select "In Memory Text Read and Write"
Then select "parse_line" and you have the reference.
I just downloaded m32v82r to be sure I had the latest and this doesn't appear in the in the list or I'm not understanding your instructions here.
Hi Jimg,
parse_line is a member function of masm32.lib Have a look at C:\masm32\include\masm32.inc:
; -----------------------------------------------
; read and write lines of text to and from memory
; -----------------------------------------------
readline PROTO :DWORD,:DWORD,:DWORD
writeline PROTO :DWORD,:DWORD,:DWORD,:DWORD
tstline PROTO :DWORD
parse_line PROTO :DWORD,:DWORD <----- Here is the function
Thanks Vortex, but my copy of C:\masm32\include\masm32.inc is only 8K long, and these lines are definitely not in there. They are not in the one in the latest download either. What's going on here???
They are in the 8.2a patch. That's the reason that i could not find them either.
Thanks Rain Dog. Dang, how'd I miss that update? :red
Attached is a file you might find useful.
Paul
[attachment deleted by admin]
Hi Jimg,
Sorry, I missed it. Here is the latest version of macros.inc dated 15 Jan 2005
[attachment deleted by admin]
Here is my latest FindFirstOf
Can anyone improve on it without adding .IF etc macros?
;returns -1 if not found, otherwise returns 0 based location of character in
;ECX
FindFirstOf proc
;esp + 12 = character to look for
;esp + 16 = dword ptr to address of string to search
;esp + 20 = length of string
LOCAL strlength :DWORD
mov eax, DWORD ptr[esp+20] ;move string length to eax
mov strlength, eax ;move length of string in eax to strlegnth
mov ecx, 0 ;we will use ECX to store our index
mov edx,DWORD PTR[esp+16] ;set edx to start of string
back:
cmp ecx, strlength ;test if we are at last char of string
je done ;if we are, we did not find character
mov al,BYTE PTR[EDX + ecx] ;move char at edx to al
cmp al,BYTE ptr[esp+12] ;esp is the character we want to look for.
je found ;if not same, go to start of loop
inc ecx ;set index to the next position in str
jmp back ;it was the same, so go to found
done:
mov ecx, -1 ;not found
found:
add esp, 20 ;balance stack
ret
FindFirstOf endp
Does szMid append a 0 to the string it creates?
EDIT: The wonders of open source code! szMid does in fact append the null terminating character.
Rain Dog,
Kindly, could you re-check the formatting of your code above? It's hard to read.
Rain Dog,
Quote
Here is my latest FindFirstOf
Can anyone improve on it without adding .IF etc macros?
See the later part of this link. Look for MFNDCHR. Ratch
http://www.masmforum.com/simple/index.php?topic=170.30