I'd like to do this without having to read the whole file to count the number of lines, like this:
Code: Select all
While Eof(0)=0
Lines+1
ReadString()
Wend
Thanks for the help,
Killswitch

Code: Select all
While Eof(0)=0
Lines+1
ReadString()
Wend
Code: Select all
*Buffer.Byte = AllocateMemory(ReadData(Lof()))
While *Buffer\b <> 0
If *Buffer\b = 10
NbLines+1
EndIf
*Buffer+1
Wend
FreeMemory(*Buffer)
Code: Select all
FileName.s = ***
If ReadFile(0, FileName)
*Buffer.Byte = AllocateMemory(Lof())
ReadData(*Buffer, Lof())
While *Buffer\b <> 0
If *Buffer\b = #LF
NbLines+1
EndIf
*Buffer+1
Wend
FreeMemory(*Buffer)
EndIf
Debug NbLines (or any code you want)
End

Code: Select all
#FileName = "Whatever.txt"
IndexBufferSize = 8
IndexBufferOffset = 4
*IndexBuffer = AllocateMemory(IndexBufferSize)
*IndexBuffer
FileName.s = #FileName
If ReadFile(0, FileName)
*Buffer.BYTE = AllocateMemory(Lof())
PokeL(*IndexBuffer, *Buffer)
ReadData(*Buffer, Lof())
While *Buffer\b <> 0
;Replace CRs and LFs with 0 so they now make the end
;of a string.
If *Buffer\b = #LF
*Buffer\b = 0
NbLines+1
PokeL(*IndexBuffer + IndexBufferOffset, *Buffer + 1)
IndexBufferOffset + 4
If IndexBufferOffset > IndexBufferSize - 4
IndexBufferSize * 2
*NewIndexBuffer = ReAllocateMemory(*IndexBuffer, IndexBufferSize)
If *NewIndexBuffer = 0
MessageRequester("Fatal Error", "Cannot allocate memory")
End
Else
*IndexBuffer = *NewIndexBuffer
EndIf
EndIf
ElseIf *Buffer\b = #CR
*Buffer\b = 0
EndIf
*Buffer+1
Wend
EndIf
Dim Lines.s(NbLines)
For i = 1 To NbLines
Lines(i) = PeekS(PeekL(*IndexBuffer + ((i-1) * 4)))
Next i
FreeMemory(*Buffer)
FreeMemory(*IndexBuffer)
For i = 1 To NbLines
Debug Lines(i)
Next i
Code: Select all
Procedure CountLinesInTextFile(file$)
If ReadFile(0,file$)
l=Lof() : m=AllocateMemory(l)
If m : ReadData(m,l) : m$=PeekS(m) : FreeMemory(m) : EndIf
CloseFile(0)
EndIf
ProcedureReturn CountString(m$,Chr(10))
EndProcedure
Debug CountLinesInTextFile("c:\test.txt")
Code: Select all
Procedure.l LoadTextMem(fileID,file.s) ; Returns 0 if not enough memory or open failed!
Protected fileID,fhdl,*buffer,Size,readsize,*ptr.BYTE,*ptrend,Lines,c,n,*strptr,Length,maxlength
If file
fhdl=ReadFile(fileID,file)
If fhdl=false : ProcedureReturn 0 : EndIf
Else
If IsFile(fhdl)=false : ProcedureReturn 0 : EndIf
UseFile(fhdl)
fhdl=fileID
EndIf
If fhdl
Size=Lof()
If Size>0
*buffer=AllocateMemory(Size+16)
If *buffer
readsize=ReadData(*buffer+16,Size) ;header is 16 bytes
PokeL(*buffer,readsize) ; Text file size
*ptr=*buffer+16
*ptrend=*ptr+readsize
If *ptr<*ptrend
Lines=0
While *ptr<*ptrend
While *ptr<*ptrend
c=*ptr\b : *ptr+1
If c=13 : Break : EndIf
If c=10 : Break : EndIf
Wend
If *ptr<*ptrend
n=*ptr\b
If n+c=23 : *ptr+1 : EndIf
Lines+1
EndIf
Wend
PokeL(*buffer+4,Lines) ; Number of lines
EndIf
*index=AllocateMemory(Lines*8)
If *index
PokeL(*buffer+8,*index) ; Index pointer
*ptr=*buffer+16
*ptrend=*ptr+readsize
If *ptr<*ptrend
Lines=0
While *ptr<*ptrend
Length=0
*strptr=*ptr
While *ptr<*ptrend
c=*ptr\b : *ptr+1
If c=13 : Break : EndIf
If c=10 : Break : EndIf
Length+1
Wend
If *ptr<*ptrend
n=*ptr\b
If n+c=23 : *ptr+1 : EndIf
PokeL(*index+(Lines*8),*strptr)
PokeL((*index+4)+(Lines*8),Length)
PokeB((*strptr+Length)+1,0) ; places a 0 terminator where the EOF is.
Lines+1
If maxlength<Length : maxlength=Length : EndIf
EndIf
Wend
EndIf
PokeL(*buffer+12,maxlength) ; Maximum string length
Else
FreeMemory(*buffer)
ProcedureReturn 0
EndIf
ProcedureReturn *buffer
EndIf
EndIf
If file Or fileID=#PB_Any : CloseFile(fhdl) : EndIf
EndIf
ProcedureReturn 0
EndProcedure
Procedure FreeTextMem(*buffer) ; Free text buffer and index memory
Protected *index
If *buffer
*index=PeekL(*buffer+8)
If *index
FreeMemory(*index)
EndIf
FreeMemory(*buffer)
EndIf
EndProcedure
Procedure.l CountTextMem(*buffer) ; Return number of lines
Protected *index
If *buffer
ProcedureReturn PeekL(*buffer+4)
EndIf
ProcedureReturn 0
EndProcedure
Procedure.l MaxLengthTextMem(*buffer) ; Return length of the longest string
Protected *index
If *buffer
ProcedureReturn PeekL(*buffer+12)
EndIf
ProcedureReturn 0
EndProcedure
Procedure.s ReadTextMem(*buffer,line) ; Return specified line as string, "" if error or empty, range 0 to CountTextMem(*buffer)-1
Protected *index,Length,*strptr
If *buffer
*index=PeekL(*buffer+8)
*strptr=*index+(line*8)
Length=PeekL(*strptr+4)
If Length>0
ProcedureReturn PeekS(PeekL(*strptr),Length)
EndIf
EndIf
ProcedureReturn ""
EndProcedure
Procedure.l PointerTextMem(*buffer,line) ; Return pointer to string, 0 if error, range 0 to CountTextMem(*buffer)-1
Protected *index,Length,*strptr
If *buffer
*index=PeekL(*buffer+8)
ProcedureReturn PeekL(*index+(line*8))
EndIf
ProcedureReturn 0
EndProcedure
Procedure.l LengthTextMem(*buffer,line) ; Return length of string, 0 if error or empty, range 0 to CountTextMem(*buffer)-1
Protected *index
If *buffer
*index=PeekL(*buffer+8)
ProcedureReturn PeekL((*index+(line*8))+4)
EndIf
ProcedureReturn 0
EndProcedure
Code: Select all
XIncludeFile "LoadText.pbi"
#TextFile=0
TextFile$=OpenFileRequester("Please choose file to load","F:\","Text (*.txt)|*.txt",0)
If TextFile$
*textptr=LoadTextMem(#TextFile,TextFile$)
linestotal=CountTextMem(*textptr)
Debug "Number of lines: "+Str(linestotal)
Debug "Longest line: "+Str(MaxLengthTextMem(*textptr))
line=0
While line<linestotal
Debug ReadTextMem(*textptr,line)
line+1
Wend
FreeTextMem(*textptr)
EndIf

Code: Select all
Procedure.l TextCountChars(*Text.b,*CharacterToFind.s,TextLenght.l)
!mov edi,dword[esp] ;pointer to the first character in string (first function parameter)
!;cld ;clear DF (Direction Flag). (normally not necessary; cleared by default)
!xor ebx,ebx ;init counter to NULL
!mov ecx,dword[esp+8] ;lets set # characters
!inc ecx
!jecxz near CountCharsgo ;if 0, then exit returning 0
!mov edi,dword[esp] ;point again to the first character in string (first function parameter)
!mov eax,dword[esp+4]
!mov al,byte[eax] ;al=character to find
!@@:REPNZ scasb ;repeat comparing AL CPU register content with byte[edi]
!jecxz near CountCharsgo ;until ecx value is reached
!inc ebx ;or a match is found
!jmp near @r ;continue comparing next character
!CountCharsgo:MOV eax,ebx ;output the matches counter
ProcedureReturn
EndProcedure