The MASM Forum Archive 2004 to 2012

Miscellaneous Forums => 16 bit DOS Programming => Topic started by: cecil1887 on March 22, 2012, 06:23:55 PM

Title: How to filter alphabets and whitespace only in WinAsm?
Post by: cecil1887 on March 22, 2012, 06:23:55 PM
Hi, I want to write a program that allows the user to enter a sentence of up to 99 characters.
The program shall then remove characters other than alphabet and white space from the input
string and display the total number of alphabets entered by the user.

Example:
Input string:
Hello ???+-09258World

Output:
Hello World

Count:
11

Can anyone please help??
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: jj2007 on March 22, 2012, 06:37:02 PM
Pure assembler :green

include \masm32\MasmBasic\MasmBasic.inc   ; download (http://www.masm32.com/board/index.php?topic=12460)
  Init
  Let esi=""
  .Repeat
   Inkey
   mov ebx, eax   ; save to a "safe" register
   .if Instr_(Chr$("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ", 9), Chr$(ebx))
      Let esi=esi+Chr$(ebx)
      Print Chr$(ebx)
   .endif
  .Until ebx==13 || Len(esi)>=99
  Inkey CrLf$, "Your string: [", esi, Str$("] with %i bytes", Len(esi))
  Exit
end start
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 22, 2012, 07:12:20 PM
lol
that's not "pure"   :P

try this one...
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: jj2007 on March 22, 2012, 07:25:04 PM
268 vs 14 lines - and yours does not even block the illegal input ::)

But it's 16-bit code, in contrast to mine. so I will be generous:  :U
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 22, 2012, 07:28:45 PM
block what illegal input ?

ohhh - you mean it accepts everything into the buffer, then strips it out
well - that's just the easiest way to do it, seeing as i already have the routine in place   :P
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: cecil1887 on March 22, 2012, 07:36:21 PM
dave your output is correct, it should not block any characters. accept everything to input then remove any character other than alphabets & spaces. is it possible to do it in a fewer lines of code?
all of your immediate help  very much appreciated!
thanks.
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 22, 2012, 07:39:25 PM
yah - i could move all the code into the loop
but, you wouldn't be able to use the code for other programs   :P
i try to write routines that may be used over and over
and - i am sure there is an easier way to filter the string - but the way i did it is simple - easy to understand
for example, i could use a look-up-table
but that is overkill, i think   :bg

let me add that Jochen's code is a lot bigger, if you take his MasmBasic library into account
it just looks smaller because he uses a lot of macros
my program is 754 bytes of EXE - how small you want it - lol
if i made a tiny model version, it would be 242 bytes or less
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: cecil1887 on March 22, 2012, 07:49:51 PM
it would be great if u can minimize the codes as much... as long as it do work,
1. read input
2. filter input
3. output result with count

i think i would prefer a tiny model if u can deliver?
thanx :D
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: cecil1887 on March 22, 2012, 09:11:54 PM
title loop
.dosseg
.model small
.stack 100h

.data
msg db "Enter string:"
input db 99 dup(0);duplicate 99 bytes, and values are undefined '?', can fill a value instead
blank   db 0Ah, 0Dh,'$'

.code
main proc

mov ax, @data
mov ds, ax

mov dx, offset msg
mov ah, 9
;int 21h
mov si, offset input
again : mov ah, 1
int 21h
cmp al, 0Dh     ;ASCII code for 'enter'
je stop
mov [si], al
inc si
    jmp again

stop : mov dx, offset blank ;need to print a blank space or '\n' so the out put goes to the next line
mov ah, 9
int 21h

mov bl,'$'
mov [si], bl
mov ah, 9
mov dx, offset input
int 21h

mov ah, 1
int 21h

mov ax, 4c00h
int 21h

main EndP
end main


This code is without a filter. So when you enter a string, it will output the same string. I need to insert a filter whereby compare characters and truncate all characters except alphabets & spaces.

Please give your feedbacks  :bg
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 22, 2012, 09:59:37 PM
well - many of the lines in my program are simply documentation and to make it more legible
for example...
;********************************************************************

PrStr   PROC    NEAR
;
;Get User Input String With Prompt
;
;Call With: DX = address of prompt string to display
;
;  Returns: CX = number of characters entered
;           DX = address of '$' terminated user entered string
;
;Also Uses: all other registers are preserved
;           the "InpBuf" buffer is used to hold the string
;
;------------------------------------------

        push    ax
        push    bx
        mov     ah,9
        int     21h
        mov     dx,offset InpBuf
        mov     ah,0Ah
        int     21h
        call    NewLine
        mov     cl,InpBuf.UsedBytes
        mov     ch,0
        mov     dx,offset InpBuf.Buffer
        mov     bx,cx
        add     bx,dx
        mov byte ptr [bx],'$'
        pop     bx
        pop     ax
        ret

PrStr   ENDP

;********************************************************************


that's 19 lines of code and 18 lines for comments and "airing it out"   :bg
4 of those lines are to preserve registers - not really necessary in this case
and the proc/endp/call/return - i chose a routine that is only used once - so it could be "inlined"
believe me, your instructor won't mind the extra lines - lol
but, we can go that route, if you like
give me some time to play with it...
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 22, 2012, 10:29:47 PM
ok - here is a striped down version, 718 byte EXE
you can remove the extra comment lines, if you like

next, i will make a tiny model (.COM) version.......
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 22, 2012, 10:44:45 PM
Alpha3, 279 byte COM...
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 22, 2012, 10:47:22 PM
and, when i knock the zero's off the end of the file, 178 byte COM...
:bg
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: dedndave on March 23, 2012, 12:15:45 AM
if i strip a bunch of extra stuff out, the tiny model code looks like this   :P
        .MODEL  Tiny
        OPTION  CaseMap:None        ;case sensitive

BUFSIZE EQU 99                      ;user input buffer size, 255 max

INBUFFER  STRUCT
  MaxBytes  db BUFSIZE+1
  UsedBytes db ?
  Buffer    db BUFSIZE+1 dup(?)
INBUFFER  ENDS

;####################################################################

        .CODE
        ORG     100h

_main   PROC    NEAR

        call    NewLine
        mov     dx,offset s$Prompt1 ;'Enter a String:'
        mov     ah,9
        int     21h
        mov     dx,offset InpBuf
        mov     ah,0Ah
        int     21h
        call    NewLine
        mov     dx,offset InpBuf.Buffer
        xor     bx,bx
        mov     cl,InpBuf.UsedBytes
        mov     ch,bl
        mov     si,dx
        mov     di,dx
        jcxz    Loop03

Loop00: lodsb
        mov     ah,al
        and     ah,0DFh             ;clear bit 5 - forces upper case
        jz      Loop01              ;if it's 0 or 20h - white space

        cmp     ah,'A'
        jb      Loop02

        cmp     ah,'Z'
        ja      Loop02

Loop01: stosb
        inc     bx                  ;count it in BX

Loop02: loop    Loop00

Loop03: mov     al,'$'
        stosb
        call    StrOut
        mov     ax,bx
        call    UnsDec
        call    StrOut
        mov     dx,offset s$AnyKey  ;'Press Any Key To Exit'
        call    StrOut
        mov     ah,1                ;wait for key
        int     16h                 ;BIOS keyboard call
        mov     ah,0                ;get keyboard character
        int     16h                 ;BIOS keyboard call
        mov     ax,4C00h            ;terminate, return = 0
        int     21h                 ;DOS function call

_main   ENDP

;********************************************************************

StrOut  PROC    NEAR

        mov     ah,9
        int     21h

NewLine::
        mov     dx,offset s$CrLf
        mov     ah,9
        int     21h
        ret

StrOut  ENDP

;********************************************************************

UnsDec  PROC    NEAR

        mov     di,offset OutBuf+sizeof OutBuf-1
        mov     cx,10               ;BX = divisor

UnDec0: xor     dx,dx               ;zero the high word
        dec     di                  ;point to next string byte
        div     cx                  ;divide DX:AX by 10
        or      dl,30h              ;set ASCII bits in remainder
        mov     [di],dl             ;store the numeric character
        or      ax,ax               ;any quotient left ?
        jnz     UnDec0              ;loop until done

        mov     dx,di
        ret

UnsDec  ENDP

;####################################################################

s$Prompt1 db 'Enter a String: ',24h
s$AnyKey  db 0Dh,0Ah,'Press Any Key To Exit',24h
s$CrLf    db 0Dh,0Ah,24h
OutBuf    db 5 dup(?),24h
InpBuf    INBUFFER <>

;####################################################################

        END     _main
Title: Re: How to filter alphabets and whitespace only in WinAsm?
Post by: jj2007 on March 23, 2012, 06:39:32 AM
Quote from: dedndave on March 22, 2012, 07:39:25 PM
let me add that Jochen's code is a lot bigger, if you take his MasmBasic library into account
it just looks smaller because he uses a lot of macros

Dave,

Your example uses DOS - how big is that library?  :wink
But jokes apart: My example was meant as "real pseudo code" - just a demo what are the necessary steps (and I assumed you wanted blocking while the user types).