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??
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
lol
that's not "pure" :P
try this one...
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
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
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.
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
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 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
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...
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.......
Alpha3, 279 byte COM...
and, when i knock the zero's off the end of the file, 178 byte COM...
:bg
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
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).