The MASM Forum

General => The Campus => Topic started by: Jbarrera on March 01, 2018, 03:16:57 AM

Title: Reading Form File one Char at a time
Post by: Jbarrera on March 01, 2018, 03:16:57 AM
I have a little program I am working on, it is an area calculator. It takes the points of any shape and finds the area of the shape.
Anyway, I have the points in a text file that I will be reading in. My understanding is that the text file will be in Ascii, so I will need to convert the digits into integers.

I wanted to see how to read in the file char by char so I can convert the numbers as I read the file in.

I have done a small function to read in Ascii and convert to int from the keyboard but how do you do it from a text file.

How can I modify my readInput Keyboard function to read char by char from my file.

readInput PROC
          lea  esi,userInput       ;loads address for userInput Array
               again:                  ;re-loops
          call readChar             ;reads one char
          call writeChar             ;echos char to screen
          cmp  al,lineFeed         ;is input line feed
               je   fallout             ;exit loop
          mov  [esi],al              ;moves keyed value to array
          inc  esi                      ;bumps address by 1
               jmp  again

               fallout:
          mov  al,null             ;last value set to null
          mov  [esi],al            ;added to array
          ret
     readInput ENDP


this is how I'm reading in from file so far

.data

myBuffer    byte      300 DUP(?)
.code
main PROC

lea    edx,filename                ;load address of the name of file
call   OpenInputFile               ;opens the file for reading
mov  IFHandle,eax               ;saves the handle of the file produced by eax
mov  edx, offset myBuffer     ;move the buffer to edx
mov  ecx, offset BUF_SIZE    ;move the size of buffer to ecx
call   ReadFromFile               ;read the file

exit
end main


Thank you for your time
Title: Re: Reading Form File one Char at a time
Post by: felipe on March 01, 2018, 03:28:24 AM
I recommend you to look for an appropiate function in the masm32 library (which let you see the code too). If you don't find something you like there, or for any other reason, i suggest you to use some win32 api function like readfile or other... :idea:
Title: Re: Reading Form File one Char at a time
Post by: LordAdef on March 01, 2018, 04:22:20 AM
how is the text file going to be formatted?
Title: Re: Reading Form File one Char at a time
Post by: felipe on March 01, 2018, 05:32:58 AM
Quote from: LordAdef on March 01, 2018, 04:22:20 AM
how is the text file going to be formatted?

Quote from: Jbarrera on March 01, 2018, 03:16:57 AM
My understanding is that the text file will be in Ascii...

:idea:
Title: Re: Reading Form File one Char at a time
Post by: Jbarrera on March 01, 2018, 05:39:24 AM
Oh right sorry about that......well nothing specific, I can play around a little with the format. In general, it will be something like this

0,0 0,3 3,3 3,0 0,0 Square
or
Sqr: 0,0 0,3 3,3 3,0 0,0 (in order for the equation to work we need to loop back around to the 1st point, hence 5 points)

At 1st I read the whole data to an array and I was trying to extract the numbers into another array. I started to think if it would be easier to convert the numbers to integers as I was reading in the file one char at a time, that way I could just use one array. While there is probably a function in masm32 lib to do this, I need to manually do everything as part of my assignment.

edit: I was just thinking, would it be better to enclose the points in braces () ex. (0,0)(0,3) maybe I can use the braces as a delimiter, I'm not sure if a blank would make a good delimiter.
Title: Re: Reading Form File one Char at a time
Post by: LordAdef on March 01, 2018, 06:07:03 AM
Quote from: Jbarrera on March 01, 2018, 05:39:24 AM
Oh right sorry about that......well nothing specific, I can play around a little with the format. In general, it will be something like this

0,0 0,3 3,3 3,0 0,0 Square
or
Sqr: 0,0 0,3 3,3 3,0 0,0 (in order for the equation to work we need to loop back around to the 1st point, hence 5 points)

OK, you are going to need to code a parser, right?
This is a code I made to decompress a file (in binary). It uses InputFile(string) and alloc (DWORD Ptr [esi]). I made a prog to encode the text file into binary. I can send it you tonight if you want to check it out.

Decomp.asm:
;====================== DECOMPRESS FILE =============================
pDecompress proc, string:DWORD
      LOCAL  tLen :DWORD
      LOCAL  tLine:DWORD
      LOCAL  tSum:DWORD
      LOCAL  tLineLen:DWORD
     
; DATA BEGINS AT 16
mov tLine, 0
mov tLineLen, 0
mov tSum, 0
    LineLength = 160 ; Lenght of line is fixed to 160
   
mov   esi, InputFile(string)
          mov   tLen, ecx                  ; lenght of file in tLen

          mov map.mapDataPtr, alloc (DWORD Ptr [esi])           ; allocate dest. memory
          mov edi, map.mapDataPtr    ; MapPtr       
          m2m map.height, DWORD Ptr [esi+4]
          m2m map.style,   DWORD Ptr [esi+12]

       COMMENT @
File header:
-- Map --
Original size= DWORD Ptr [esi])
Number of lines=  DWORD Ptr [esi+4])   
Lengh of line= DWORD Ptr [esi+8])  ; fixed to 160
Map Style= DWORD Ptr [esi+12]) ;SINGLE/MIRRORED
@

; printf ("\n\n----------------- File header ---------------------\n\n")
; printf ("Original size= %d\n", DWORD Ptr [esi]) ; Original Size
;          printf ("Number of lines= %d\n", DWORD Ptr [esi+4])          ; Number of Lines
;          printf ("Lengh of line= %d\n", DWORD Ptr [esi+8]) ; Lenght of line
;          printf ("Map Style= %d\n", DWORD Ptr [esi+12]) ; Map style
;          printf ("Atual size=  %d\n", tLen ) ; New size       

mov ecx, "@@@@" ; First chunk is always 64
mov edx, 16-1 ;counter & === HEADER SIZE ===
xor ebx, ebx
     
@Main:
        add edx, 1
cmp edx, tLen
jz DoneDC ; DONE?
mov bl, SBYTE Ptr [esi+edx]
test bl, bl
js Negative
jz Zero
; ------------------------- It´s Positive:
add tLineLen, 1 ; inc line num
add tSum, ebx ; Sums line (to recouver missing chunk)
mUNROLL3 ; MUST HAVE ecx == 64 or 32
xor ecx, 01100000011000000110000001100000b ; permute 4 @@@@ to 4 spaces or vice-versa
jmp @Main

  Negative:
      add tLineLen, 1
    ; ---------- imul neg value in line ------------ 
neg bl
mov ecx, "    " ; moved here for interdep.   Neg is always 32
add tSum, ebx ; sums chunk item
mUNROLL3 ; ecx == 64 or 32
; ----------- Missing chunk -----------
mov ebx, LineLength
xor ecx, 01100000011000000110000001100000b ;ecx carries tChar val
sub ebx, tSum ; Missing chunk value

mUNROLL3
mCHECKnext
  add tLine, 1
jmp @Main
  Zero: ; Copy last line from edi itself. Uses MemCopy, dword.
mov eax, edi
sub eax, LineLength
invoke MemCopy, eax, edi, LineLength
add edi, LineLength

mCHECKnext ;check if next val is zero -> makes LineLen & Sum = 0
add tLine, 1
mov ecx, "@@@@" ; next line always starts with 64
jmp @Main

  DoneDC:
  ; --------- return values -----------------------
free esi
          xor edi, edi

;          mov   edi, offset  map.mapDataPtr ;MapPtr
; xor ebx, ebx
;       @@:
;        printf ("%c", BYTE Ptr [edi])
;        add edi, 1
;        add ebx, 1
;        cmp ebx, 320 ;30000 ;00 ;DWORD Ptr [esi]
;        jnz @B

    invoke pIniLinePtrArray ; initializes map.mapLinePtr
    invoke pLoadMapData, gm.level ; bad name for the function "MapData" is better

ret
pDecompress endp
Title: Re: Reading Form File one Char at a time
Post by: LordAdef on March 01, 2018, 06:11:21 AM
But instead of reading from a file, you could start simpler by designing your code within the asm. Later, it is goinf to be just a matter of transfering the data into the text file and do the reading stuff.

something like

.const
Square EQU 1
Foo    EQU 2

.data
Data   dd  10,21,10,0,0,0,Square \
                   0,33,1,1,4,4, Foo


If you need to have a varied number of numbers, you may need to have an extra variable to specify it.
you file struct could be something like this:

[Amount: DWORD][function:DWORD][data:BYTE]

Data dd Amount, Funtio, data........................  \
Data dd 4, Square, 10, 20, 0, 0 \

Title: Re: Reading Form File one Char at a time
Post by: felipe on March 01, 2018, 04:16:14 PM
Quote from: Jbarrera on March 01, 2018, 05:39:24 AM
While there is probably a function in masm32 lib to do this, I need to manually do everything as part of my assignment.

Sorry, you will need to use at least a function from win32 api for accessing a file from disk.
Title: Re: Reading Form File one Char at a time
Post by: aw27 on March 01, 2018, 06:07:11 PM
There are many ways to tackle these problems, however theses irvine type assignments should be posted in the Irvine Books section of the forum. Typically teachers want the problems to be solved with the Irvine Library.
Although they are a bit boring I have solved a few in the past when posted in the irvine Books sections because I do have the Irvine Library.
You are also recommended to post the whole assignment, so we know exactly the terms, preferable the original .pdf document.
Title: Re: Reading Form File one Char at a time
Post by: Jbarrera on March 02, 2018, 04:39:37 AM
aw27 you are correct the Irvine library is needed for this program. I apologize, I did not realize there was a section for Irvine down in the miscellaneous section. I will look in there