|
Post by Walt Decker on Jan 6, 2023 18:38:01 GMT -5
LOF stands for length of file. What does it return, with what file types does it work, and why would one want to use it?
|
|
gaslouk
Full Member
Hi from beautiful Greece.
Posts: 130
|
Post by gaslouk on Jan 7, 2023 4:52:31 GMT -5
Hi
This function returns the length as number of bytes (or characters) contained in the open file referenced by #handle. This example uses the LOF function to determine the size of an open file.
open "\folder.png" for input as #1 qtyBytes = lof(#1) for x = 1 to qtyBytes next x close #1 print qtyBytes ; end
Returns the length of the open file in characters and works with any file type.
Gaslouk
|
|
|
Post by Walt Decker on Jan 7, 2023 10:05:10 GMT -5
That is a good start, but let's expand on your code a bit. I assume that Folder.png is a small graphic that displays a directory image when rendered in some graphics app. As such it will have some type of header information followed by blocks of either red, green, blue values or an unsigned long integer.
So, let's print it out in groups of 20 characters.
' CounterMax = 20 Accumulator = 0 ChrIn$ = ""
open "\folder.png" for input as #1 qtyBytes = lof(#1) for x = 1 to qtyBytes Accumulator = Accumulator + 1
IF Accumulator = CounterMax THEN PRINT PRINT Accumulator = 0 END IF INPUT #1, ChrIn$ PRINT ChrIn$; next x close #1 PRINT print qtyBytes end '
How would you use LOF() to find the number of records(lines) in a text file so you could put those records in an array? How would you go about putting the records in the array without reading the file again? Remember that most text files are terminated with a CRLF, CR, or LF.
|
|
|
Post by Walt Decker on Jan 8, 2023 15:17:46 GMT -5
Well, let us see what can be done with this. In another thread I have posted functions similar to those presented here.
The below code is NOT TESTED so there might be errors.
' ' PUT SOME DATA IN A SEQUENTIAL FILE
CR$ = CHR$(13) + CHR$(10)
AryUbnd = 0 '<--- upper bound of array NumBytes = 0 '<--- number of bytes(characters) in file RetVal = 0 '<--- value returned from numeric function
DIM AryIn$(-1)
Stream$ = "" '<--- text as a single variable from the text file
Fname$ = "SEQ_TEST.TXT" '<--- name of sequential file
OPEN Fname$ FOR OUTPUT AS #1 PRINT #1, "The quick brown fox" PRINT #1, "Peter Piper picked a peck" PRINT #1, "Mary had a little lamb" PRINT #1, "Little Miss Muffet sat on a tuffet" PRINT #1, "The cow jumbped over the moon" PRINT #1, "Humpty Dumpty sat on a wall" CLOSE #1
T$ = "#OPN" '<--- create a tag for MAPHANDLE
NumBytes = FN.OpenBinary(Fname$, T$) '<--- open file in binary mode Stream$ = FN.StreamIn$(NumBytes, T$) '<--- get all text from the file RetVal = FN.CloseFile(T$) '<--- close the file
AryUbnd = FN.ParseStr(Stream$, CR$) '<--- split the string into its parts 'based on the indicated delimeter IF AryUbnd THEN FOR I = 0 TO AryUbnd PRINT AryIn(I) NEXT I END IF
END
'--------------------------------------------- '---------------------------------------------
FUNCTION FN.OpenBinary(NameIn$, Tag$) '############################################## ' ARGUMENTS: ' NameIn$: Path and file to open ' Tag$: Map name '##############################################
NumBytes = 0 OPEN NameIn$ FOR BNARY AS #1 '<--- open the file. If is does not exist 'it will be created NumBytes = LOF(#1) '<--- # of bytes(characters) in the file
MAPHANDLE #1, Tag$ '<--- rename the device handle
FN.OpenBinary = NumBytes END FUNCTION
'--------------------------------------------- '---------------------------------------------
FUNCTION FN.CloseFile(Tag$)
NumBytes = LOF(#Tag$) CLOSE #Tag$
FN.CloseFile = NumBytes END FUNCTION
'--------------------------------------------- '---------------------------------------------
FUNCTION FN.StreamIn$(Size, Tag$) '##################################### ' ARGUMENTS: ' Size: # of bytes(characters) in file ' Tag$: Name of device '#####################################
TxtIn$ = "" TxtIn$ = INPUT$(#Tag$, Size)
FN.StreamIn$ = TxtIn$ END FUNCTION
'--------------------------------------------- '---------------------------------------------
FUNCTION FN.ParseStr(TxtIn$, Delm$) '########################################## ' ARGUMENTS: ' TxtIn$: String to scan ' Delm$: What to scan for '##########################################
IF TxtIn$ = "" THEN '<--- string is nul FN.ParseStr = -1 EXIT FUNCTION END IF
DlmLen = 0 '<--- # of characters in delimeter Found = 0 '<--- whether delimeter is found
I = -1 '<--- array element counter
Dlm$ = "," '<--- default delimeter
IF Delm$ <> "" THEN Dlm$ = Delm$ '<--- change default
DlmLen = LEN(Dlm$) '<--- set delimeter size
NumDlms = FN.ParseCount(TxtIn$, Dlm$) '<--- get # of delimiters in string IF NumDlms THEN '<--- set # of elements in array REDIM AryIn$(NumDlms) ELSE FN.ParseStr = -1 EXIT FUNCTION END IF
[BEGIN.PARSE] '<--- scan for delimeter Found = INSTR(TxtIn$, Dlm)
IF Found = 0 THEN GOTO [PARSE.ARY.END] '<--- exit scan
I = I + 1 '<--- increase array element counter AryIn$(I) = LEFT$(TxtIn$, Found - 1) '<--- set text in array TxtIn$ = MID$(TxtIn$, Found + DlmLen '<--- truncate TxtIn$ GOTO [BEGIN.PARSE] '<--- continue scan
[PARSE.ARY.END]
FN.ParseStr = NumDlms END FUNCTION
'--------------------------------------------- '---------------------------------------------
FUNCTION FN.ParseCount(Txt$, Delm$) '############################################# ' ARGUMENTS: ' Txt$: Text string to scan ' Delm$: What to scan for ' ' NOTE: ' If no delimier is found the function will return 1 ' if Txt$ is not nul otherwise it will return zero '#############################################
IF Txt$ = "" THEN '<--- nothing to scan EXIT FUNCTION END IF
DlmLen = 0 '<--- # of characters in Dlm$
ParseCount = 0 '<--- # of delimeters found
Found = 0 '<--- whether a delimeter is found Strt = 1 '<--- position to start scanning for delimiter
Dlm$ = "," '<--- default delimeter
IF Delm$ <> "" THEN Dlm$ = Delm$ '<--- change default
DlmLen = LEN(Dlm$) '<--- delimeter characters
[PARSE] '<--- begin or continue scanning for delimter Found = INSTR(Txt$, Dlm$, Strt)
IF Found = 0 THEN GOTO [END.PARSE] '<--- exit loop ParseCount = ParseCount + 1 '<--- delimeter found so increase count Strt = Found + DlmLen '<--- set new scan position GOTO [PARSE] '<--- scan again
[END.PARSE] FN.ParseCount = ParseCount + 1 END FUNCTION '
|
|
gaslouk
Full Member
Hi from beautiful Greece.
Posts: 130
|
Post by gaslouk on Jan 9, 2023 4:06:21 GMT -5
Hi. Thank you for this valuable effort on your part. But my level is much lower than your expectations. however I tried your code, fixed some mistakes I pointed out and it worked. the results returned are these.
0 0 0 0 0 0 0 0 I believe it is correct because that particular file "SEQ_TEST.TXT" does not exist on my computer.
But even with a file that I read from my computer the result was the same.
Gaslouk
|
|
|
Post by Walt Decker on Jan 9, 2023 9:30:13 GMT -5
First, the file is created on you computer by the app, so it should be there.
Second, looking at the original code I found a syntax error, so the printout will always be zero.
If you change this: AryUbnd = FN.ParseStr(Stream$, CR$) '<--- split the string into its parts 'based on the indicated delimeter IF AryUbnd THEN FOR I = 0 TO AryUbnd PRINT AryIn(I) '<---- ERROR HERE NEXT I END IF
to this: AryUbnd = FN.ParseStr(Stream$, CR$) '<--- split the string into its parts 'based on the indicated delimeter IF AryUbnd THEN FOR I = 0 TO AryUbnd PRINT AryIn$(I) '<---- CHANGE NEXT I END IF
you should get the contents of the file as elements of the array.
As for my expectations, I expect folks to go through the code, analyze it to the point where they understand what it does, and, if they do not understand, ask why I did it this way and, perhaps, is there another way. So keep plugging away.
|
|