Parse a TAB delimited file
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