If you were to open a file into a buffer, you could parse it into strings and numbers with something like this :
Note that you can predict the length of the string...this way you will be able to keep from going out of bounds in an array, as you will already know how long the array string will be
LOCAL
DIM a,counter
DIM TheString$
LOCAL FN ReadNumber%(StrHndl&)
THESTRING$ = ""
FOR counter = 1 TO 8
a = PEEK([StrHndl&] + goffset&)
INC(gOffSet&)
LONG IF a = 13
EXIT FN
END IF
THESTRING$ = THESTRING$ + CHR$(a)
NEXT counter
END FN = VAL(TheString$)
LOCAL
DIM a,counter
DIM TheString$
LOCAL FN ReadText$(myLength,StrHndl&) 'myLength...controls what comes out
THESTRING$ = ""
counter = 0
FOR counter = 1 TO 50 'I just knew that I would never have over 50
a = PEEK([StrHndl&] + goffset&)
INC(gOffSet&)
LONG IF (a = 9) OR (a = 13) 'this is a tab or a return
GOTO "here" 'get out quick
END IF
THESTRING$ = THESTRING$ + CHR$(a) 'put it in the string
NEXT counter
"here" : 'goto location
theString$ = FN ClipOString$(theString$,myLength) ' routine I have to
'keep strings from going out of bounds
END FN = TheString$
I have posted this before, and did not get beat up too bad for using a global (goffset&) to keep track of where we are in the file. BTW, this is part of a PG project. This puppy took a file processing from 15 minutes to about 3 seconds.
Get the file in the buffer like this :
FN pGopenFile
LONG IF LEN(gFileName$)
CURSOR _watchCursor
OPEN "I",#3,gFileName$,,gFileVol
fileSize& = LOF(3,1)
StrHndl& = FN NEWHANDLE(fileSize&)
LONG IF StrHndl&<>_nil 'enough memory
osErr% = FN HLOCK(StrHndl&) 'not sure we need this
READ FILE#3,[StrHndl&],fileSize& "This will get it in a hurry
osErr% = FN HUNLOCK(StrHndl&) 'not sure we need this
XELSE
osErr% = _mFulErr
FileSize& = 0 'just my way of deciding if I should parce
END IF
CLOSE #3
<etc.>
I've been playing with extracting routines again and thought I would pass along the functions for anyone else who didn't want to reinvent any wheels.
These two functions will extract and field from a tab delimited file. All that needs to happen is for the function to know how many fields are in the file and thats usually contained on the first line of the tab delimited file.
LOCAL FN countFields(temp$):' counts the number of fields
totalFields=0
FOR count=0 TO LEN(temp$):' scan the line for fields
LONG IF MID$(temp$,count,1)=CHR$(9):' look for the tab fields
INC(totalFields):' add 1 to the count
END IF
NEXT count
INC(totalFields):' this is for the last field
END FN=totalFields
'
LOCAL FN extractField$(theString$,theFld,totalFlds)
SELECT theFld:' see which field we want
CASE 1:' want the first field item
thePos=INSTR(1,theString$,CHR$(9)):' find the first field end
DEC(thePos):' minus from the position we found it at
temp$=MID$(theString$,1,thePos):' extract portion of the string
CASE totalFlds:' want the last field
thePos=1:' where to start searching from
DO
thePos=INSTR(thePos,theString$,CHR$(9)):' look for tabs
LONG IF thePos:' did we find a field
INC(thePos):' where to resume the next search position
startPos=thePos:' save this position
END IF
UNTIL thePos=0:' loop til we get the positon of last field
temp$=MID$(theString$,startPos,250):' get last part of the str
CASE ELSE:' otherwise we want this item in the fields
count=1:' where to start searching
thePos=1:' where to start searching from
DO
thePos=INSTR(thePos,theString$,CHR$(9)):' look for tabs
LONG IF thePos:' did we find a field
INC(count):' add 1 to the field counter
INC(thePos):' where to resume the next search position
END IF
UNTIL count=theFld:' loop til we get the positon of field
startPos=thePos:' where the data starts in the string
endPos=INSTR(thePos,theString$,CHR$(9)):' look for next tabs
theLen=endPos-startPos:' how much to copy out
temp$=MID$(theString$,startPos,theLen):' get this much of it
END SELECT
END FN=temp$
To use them in a program, I do it either at import or export (depending on if I am munging data on the way in or out). My sample array is "posted$", just replace this with your own. Note, if you're reading in a tab file, you can process one line at a time.
numbFields=FN countFields(posted$(0)):' go count the fields for me first
FOR count=0 TO totalLines:' we have this many lines to process
temp$=theLine$:' we need to build the line each time
'
firstName$=FN extractField$(posted$(count),1,numbFields):' get first field
'
' do what you want with the extracted data here
NEXT count