Qbasicnews.com

Full Version: random access of fixed length text files
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
An old trick I used with QBasic/VB to handle fixed width records in an ASCII text file was to define the "fields" in the records as a UDT and use random file acess to quickly read sections of the text file without having to input each line and mid$() what I needed.

The following code is a simple test for what I am trying to do. It has been adjusted to make the reading of the record sizes correct (4 byte AS STRING for an actual 5 character field).
Code:
TYPE myrec field = 1
  first AS STRING * 4
  second AS STRING * 4
  third AS STRING * 4
  fourth AS STRING * 4
  crlf as byte
END TYPE
DIM filerec AS myrec
DIM reccount AS LONG

OPEN "test1.txt" FOR RANDOM AS #1 LEN = LEN(filerec)
reccount = LOF(1) / LEN(filerec)
PRINT reccount
PRINT LEN(filerec)

get #1, 1, filerec
print filerec.first
print filerec.second

CLOSE #1
SLEEP

The file being processed is as follows:
Code:
11111ABCDE>>>>><<<<<
22222ABCDE>>>>><<<<<
33333ABCDE>>>>><<<<<
44444ABCDE>>>>><<<<<
55555ABCDE>>>>><<<<<

The ouput for the example shows:
Code:
5
21
11111ABCDE>>>>><<<<<
ABCDE>>>>><<<<<

So it is not limiting the AS STRING * to the size defined.
There's no way of that work if the file wasn't created by FB's PUT#, as FB fixed-len strings are null-terminated, they will always be length given plus 1.

Also, crlf has to be a short.
Well, like I said, it was an old trick. However, I used the trick in Quick BASIC, pascal, C, and other "flavor" compilers. It is reading fixed width fields in an ASCII text file that pre-exists the program.

I use this method to convert a lot of file formats from/to POS systems to build initial scan files.

I'll find a way around it. 8)
Does anyone know of an easier way to convert:

Code:
type myrec
  field1(20) as byte
  crlf(2) as byte
end type

which reads a string of 20 ASCII character from a file, into a string easier than looping through each "character":

Code:
dim myfield as string
for counter = 0 to ubound(filerec.field1)
  myfield1 = myfield1 + chr$(filerec.field1(counter))
next counter

I have played around with pointers with no immediate success...
Only if field1 is null-terminated, you could do:

mystring = *@mytype.field1(0)

FB accepts assignaments of strings to byte ptrs and vice-versa.

Btw, it should be "field1(0 to 19) as byte" to read 20 bytes. In FB (as in VB/QB), the assumed lower-bound is 0 (unless change by option base) and the arrays have (upper-bound - lower-bound)+1 items.
Quote:Only if field1 is null-terminated

So I am still looking at having to move a "field1(19) as byte" 20 characters worth of information to a temp1(20) array which has the 20th element = 0 if I want to make a usable string out of it...