FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

DISK I/O

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.>
George

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
Mel Patrick