hi, i would like to use a word file for an application. every word is seperated from the other by 13,10 (linefeed). how to access for example the 5th word? i tried something but it doesn't really work. btw: i don't want to use a listview control to solve that.
first the GotoLine function is called and then the ReadWord function what's wrong with this code? it crashes my app. tnx
;first open the file invoke CreateFile,addr FileName,GENERIC_READ,0,0,OPEN_EXISTING,0,0 mov FileHandle,eax invoke GetFileSize, eax, 0 mov file_size, eax invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,eax mov hMemory,eax invoke GlobalLock,hMemory mov pMemory,eax invoke ReadFile,FileHandle,pMemory,file_size,ADDR bytes_read,NULL invoke CloseHandle,FileHandle ;goto a special line ;LinePointer is a dd variable GotoLine proc uses esi edi ebx edx lnnumber:DWORD mov edi,pMemory mov al,13 mov ecx,file_size mov ebx,lnnumber beginning: repne scasb .if ecx!=0 .if ebx>0 dec ebx jmp beginning .else add edi,2 mov LinePointer,edi .endif .endif invoke MessageBox,NULL,pMemory,addr szDisplayName,0 ;this messagebox never appears ret GotoLine endp ;now read the word in the line into a buffer ReadWord proc uses edi esi ebx edx mov esi,LinePointer lea edi,szZuRatWort cld copy_loop: movsb lodsb .if al==13 jmp out_here .endif loop copy_loop out_here: invoke MessageBox,NULL,addr szZuRatWort,addr szDisplayName,0 ;doesn't appear too ret ReadWord endp
I don't have any modular code to hand to paste up but I'll try and explain my method of loading text. The code posted is part of the next tutorial and load a series of numbers from a text file. Its modified and should be looked on a something to learn from, not to just copy and assume it works as it probably won't. Therefore I'll explain it here. I hope your writing the text files yourself, this allows you to format it for easy loading. Simply seperate each item or work by a space after it. even at the end of a line up a space before a 13,10 then do the search yourself, don't bother with rpne etc Start with edi as a pointer to the string set esi to the same. read into al, see if its equal to 32 (space). If it is then move esi into ecx, subtract edi for ecx, then enter a loop which starts at edi and reads that byte into a buffer, then increment edi and repeat the number of time ecx indicates ( less one if you don't want the space included. Set edi to esi+1 then continue to search. If you need to account of linefeeds check after every space if its equal to 13, then youv'e got a new line, to skip it add 2 to esi and set edi to esi.
In the above code DDt1 indicated to loop for five lines
mov esi, pMemory mov edi, esi mov DDt1, 5 NxtChk: mov al, byte ptr cmp al, Space jz ANum inc esi jmp NxtChk ANum: mov ecx, esi sub ecx, edi xor edx, edx NxtLtr: mov al, byte ptr mov byte ptr buffer, al inc edx inc edi dec ecx jnz NxtLtr mov byte ptr buffer, 0 inc edi mov esi, edi cmp byte ptr , EndOfLine jnz NxtChk add edi, 2 mov esi, edi dec DDt1 jnz NxtChk
You are incrementing edi by too much after you found the correct line! Change the
in GotoLine, to "inc edi". This could have caused the crash if you were checking for the last item in your file (as adding 2 would take it passed the null pointer). You may also want to look at Icz's tut on file mapping! It'll mean that you don't need to use GlobalAlloc... This is a quick, and dirty hack of your code with tut 13:
.else add edi, 2 mov LinePointer,edi .endif
I haven't checked the ReadWord proc. Plus, remember you don't have to preserve edx.... Mirno
.386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\comdlg32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\comdlg32.lib .const MAXSIZE equ 260 .data AppName db "Win32 ASM File Mapping Example",0 ofn OPENFILENAME <> FilterString db "All Files",0,"*.*",0 db "Text Files",0,"*.txt",0,0 buffer db MAXSIZE dup(0) hMapFile HANDLE 0 .data? file_size DWORD ? hInstance HINSTANCE ? hFileRead HANDLE ? pMemory DWORD ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax mov ofn.lStructSize,SIZEOF ofn mov ofn.hWndOwner, NULL push hInstance pop ofn.hInstance mov ofn.lpstrFilter, OFFSET FilterString mov ofn.lpstrFile, OFFSET buffer mov ofn.nMaxFile,MAXSIZE mov ofn.Flags, OFN_FILEMUSTEXIST or \ OFN_PATHMUSTEXIST or OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY invoke GetOpenFileName, ADDR ofn .if eax==TRUE invoke CreateFile, ADDR buffer, GENERIC_READ, 0,\ NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\ NULL mov hFileRead,eax invoke CreateFileMapping,hFileRead,NULL,PAGE_READONLY,0,0,NULL mov hMapFile,eax invoke MapViewOfFile,hMapFile,FILE_MAP_READ,0,0,0 mov pMemory,eax invoke GetFileSize,hFileRead,NULL mov file_size, eax push edi mov edi,pMemory mov al,13 mov ecx,file_size mov ebx, 3 beginning: repne scasb .if ecx != 0 .if ebx > 0 dec ebx jmp beginning .else inc edi .endif .endif invoke MessageBox, NULL, edi, NULL, MB_OK pop edi invoke UnmapViewOfFile,pMemory invoke CloseHandle,hMapFile invoke CloseHandle,hFileRead .endif invoke ExitProcess,eax end start
hey guys, thanks to ya all, but i found my own solution with the help of you. here it is:
ReadWord proc uses esi edi ebx edx lnnumber:DWORD cld mov ebx,lnnumber mov esi,pMemory .while ebx>0 mov al,byte ptr cmp al,13 jnz @F dec ebx inc esi ;|> we have to jump over 10 @@: inc esi .endw xor ecx,ecx @@: mov al,byte ptr cmp al,13 je _ready mov byte ptr buffer,al inc ecx inc esi jmp @B _ready: ret ReadWord endp