News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

String manipulation fucntions.

Started by Rain Dog, January 22, 2005, 10:01:30 PM

Previous topic - Next topic

Rain Dog

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

Rain Dog

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

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Rain Dog

I can't seem to find the parse_line procedure in any of the help files.

hutch--

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.

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Rain Dog

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

Jimg

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.

Vortex

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

Jimg

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???

Rain Dog

They are in the 8.2a patch. That's the reason that i could not find them either.

Jimg

Thanks Rain Dog.  Dang, how'd I miss that update? :red

pbrennick

Attached is a file you might find useful.
Paul


[attachment deleted by admin]

Vortex

Hi Jimg,

Sorry, I missed it. Here is the latest version of macros.inc dated 15 Jan 2005

[attachment deleted by admin]

Rain Dog

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

Rain Dog

#14
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.