News:

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

Reading Text File Line by Line

Started by Force, February 16, 2012, 07:23:46 PM

Previous topic - Next topic

Tedd

There's no need to delimit both the start and end of a line - choose one or the other.
It's more common to indicate the end of a line, as you know the file starts are the beginning of the first line.

So the first line is all characters from the beginning of the file to the first newline character.
The second line is all characters from the next character to the next newline character.
And so on..

You just read one line at a time, stopping at each newline character. Process the line. Then continue for the next line.
For the end of the file, you can either add a 0, or if you want to keep everything in text, add a blank line (another newline, with no 'data') and exit when you try to process a line of zero length.
No snowflake in an avalanche feels responsible.

Force

ok ok Thanks Tedd  :U

I understand what you mean now and ur recommend will make my code shorter

no i wont add '0' eof   .... by doing   mov ecx,filesize   is better way

so i can control Loop     with      > dec ecx

but i dont know if using filesize is a good idea or not yet
Never Stop Until You Are Better Than The Best

dedndave

i'd be more interested in line length   :P
get the length of each line, either 13 or 10 terminates a line
add the length of the previous line to the start pointer - if that value exceeds the end of file, truncate
if you come across a line that has 0 length, you have a 13,10 or similar
add 1 and try again

Force

Yes Dave
its another good idea
i will try all of them in next project hope i will find the best way 
Never Stop Until You Are Better Than The Best

dedndave

yah - if it is practical, make an array with 2 dwords for each line - the pointer and the length
then, when you are processing lines, you work from the array
you want to see what is in line 45 ? - index into the array and bang, you have the pointer and the length
this keeps you from having to move a bunch of strings around or editing the EOL chars

hutch--

Depends what you have to do with the text. Here is a test piece with 2 versions of the same algo, one with and the other without the line counter. It does nothing more than create an array of pointers to the start of every line of text. The purpose of this technique is to be able to find the start of lines when you want to process text line by line but be able to scan either direction at a byte level.



IF 0  ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                      Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include\masm32rt.inc

    ttok         PROTO psrc:DWORD,parr:DWORD
    ttok2        PROTO psrc:DWORD,parr:DWORD

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL pMem  :DWORD
    LOCAL parr  :DWORD
    LOCAL lcnt  :DWORD
    LOCAL pbuf  :DWORD
   
    LOCAL buffer[1024]:BYTE

    mov pMem, InputFile("vistaxp.h")

    REPEAT 8

  ; -------------------------------------
  ; pMem is the source to tokenise
  ; ADDR parr is a variable that receives
  ; the address of the array of pointers
  ; -------------------------------------

    invoke GetTickCount
    push eax

    invoke ttok,pMem,ADDR parr
    mov lcnt, eax

    invoke GetTickCount
    pop ecx
    sub eax, ecx

    print ustr$(eax)," ms",13,10

    ;; free parr

  ; ----------------------------

    invoke GetTickCount
    push eax

    invoke ttok2,pMem,ADDR parr
    mov lcnt, eax

    invoke GetTickCount
    pop ecx
    sub eax, ecx

    print ustr$(eax)," ms",13,10

    ENDM

    free parr
    free pMem

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

ttok proc psrc:DWORD,parr:DWORD

  ; ----------------------------------------------------------------------------------
  ; scan source text and create an array of pointers to the beginning of each line of text
  ;
  ; psrc = the text tokenise
  ; parr = the address of a variable that has the array memory address written to it
  ;
  ; return values
  ; 1. the line count in psrc
  ; 2. an array of pointers written to parr
  ;
  ; parr should be deallocated with GlobalFree() or the "free" macro within the scope
  ; that the variable "parr" was allocated in
  ; ----------------------------------------------------------------------------------

    LOCAL hMem  :DWORD
    LOCAL lcnt  :DWORD

    mov edx, psrc
    sub edx, 1
    xor eax, eax

; -------------------
; count ASCII 10 (LF)
; -------------------
    jmp lbl0

  pre0:
    add eax, 1
  lbl0:
    add edx, 1
    movzx ecx, BYTE PTR [edx]
    cmp ecx, 10
    je pre0
    test ecx, ecx
    jnz lbl0

    mov lcnt, eax               ; store the line count
    lea eax, [eax*4]            ; mul EAX by 4
    mov hMem, alloc(eax)        ; allocate "lcnt" * 4
    mov edx, hMem               ; store address in EDX

    mov eax, psrc
    mov [edx], eax              ; write pointer to 1st line
    add edx, 4

; ------------------------------------------------------
; loop through text writing a pointer to each line start
; ------------------------------------------------------
    sub eax, 1

  mainloop:
    add eax, 1
  backin:
    movzx ecx, BYTE PTR [eax]
    test ecx, ecx
    jz zero
    cmp ecx, 10                 ; test for LF
    jne mainloop

  wrtptr:
    add eax, 1                  ; inc to next char past LF
    mov [edx], eax              ; write line start to array member
    add edx, 4
    jmp backin

  zero:
    mov ecx, parr               ; load passed handle address into ECX
    mov edx, hMem
    mov [ecx], edx              ; store local array handle at address of passed handle

    mov eax, lcnt               ; return the line count

    ret

ttok endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

align 16

ttok2 proc psrc:DWORD,parr:DWORD

  ; ----------------------------------------------------------------------------------
  ; scan source text and create an array of pointers to the beginning of each line of text
  ;
  ; psrc = the text tokenise
  ; parr = the address of a variable that has the array memory address written to it
  ;
  ; return values
  ; 1. the line count in psrc
  ; 2. an array of pointers written to parr
  ;
  ; parr should be deallocated with GlobalFree() or the "free" macro within the scope
  ; that the variable "parr" was allocated in
  ; ----------------------------------------------------------------------------------

    LOCAL hMem  :DWORD
    LOCAL lcnt  :DWORD

    mov hMem, alloc(1024*1024*8)
    mov edx, hMem               ; store address in EDX

    mov eax, psrc
    mov [edx], eax              ; write pointer to 1st line
    add edx, 4

; ------------------------------------------------------
; loop through text writing a pointer to each line start
; ------------------------------------------------------
    sub eax, 1

  mainloop:
    add eax, 1
  backin:
    movzx ecx, BYTE PTR [eax]
    test ecx, ecx
    jz zero
    cmp ecx, 10                 ; test for LF
    jne mainloop

  wrtptr:
    add eax, 1                  ; inc to next char past LF
    mov [edx], eax              ; write line start to array member
    add edx, 4
    jmp mainloop

  zero:
    mov ecx, parr               ; load passed handle address into ECX
    mov edx, hMem
    mov [ecx], edx              ; store local array handle at address of passed handle

    mov eax, lcnt               ; return the line count

    ret

ttok2 endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

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

Force

Hutch
I cant Assemble n link  ur code
in fact I noticed that I cant assemble any code including masm32rt.inc
I got this problem 1st time I dont know Whats wrong I m thinking now What I changed in my pc  :red

I mean There is no error but it dsnt work
Never Stop Until You Are Better Than The Best

hutch--

Something in your installation must be broken, just re-install it again and make sure its all there when you finish.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Force

re-installing but

still same problem :red
Never Stop Until You Are Better Than The Best

dedndave

the masm32 folder must be in the root

C:\masm32 will work
C:\Programming\masm32 will not work

make sure the files you are trying to build are on the same drive as masm32

it's a good idea to close all other programs when installing

Force

I re-installed a few times i got same problem

after uninstalling a C compiler which i installed yesterday

I installed masm32 again .It works without problem now  :eek
Never Stop Until You Are Better Than The Best

Force

Thanks Hutch
sure ur code will help me

btw I wanna ask you a question 
when I play with codes i made a simple project

"sending message to editbox of another program and pushing button of it then message is in messagebox"
I used Findwindow,Findwindowex Method

I wanna post it to forum but i m not sure if its illegal for this forum or not
Never Stop Until You Are Better Than The Best

dedndave

we all use FindWindow from time to time   :P
as long as you are not reversing someone elses software and it isn't virus related, Hutch doesn't usually mind

...oh - and post no pix of nakie ladies
....unless they are blonde
......and not Kylie Minogue - lol

Force

Never Stop Until You Are Better Than The Best