8 File Storage
The direct-word PRINT# statement stores data items in specific records of a file. The data is written to the specific file number and record number, starting at the word addressed by word pointer. The word pointer can be an integer expression in the range 1 through (bytes-per-record/2)+1. If the word pointer is exactly one greater than the highest word in the record, that word pointer will address the first word of the next record.
Example: If there are 256 bytes per record, and the word pointer is 129, the following would be equivalent:
PRINT #1,1,129 PRINT #1,2,1The optional END parameter places an EOF after the last data item printed. When END is not used, the remainder of the record is left unchanged. Remember that ON END# and TYP can be used to detect EOFs, as explained later in this chapter.
Listed below is an example program which opens a 1,000-record file named STOCK. Each record can contain 256 bytes of data about each part to be stocked. For now the program enters only four items--part number, description, unit cost, and current quantity on hand.
10 ! 20 ! OPEN NEW STOCK FILE 30 ! 40 CREATE "STOCK",1000 50 DIM Part$[20],Desc$[20] 60 ASSIGN #1 TO "STOCK" 70 INPUT "TODAY'S DATE:";Date$ 80 PRINT LIN(5),SPA(30),"PARTS SET UP FOR",Date$ 90 PRINT "PART NO. DESCRIPTION",TAB(40),"UNIT COST QTY. ON HAND",LIN(2) 100 FOR Record=1 TO 1000 110 INPUT "PART NUMBER?";Part$[1,20] 120 IF UPC$(Part$[1,4])="DONE" THEN 220 130 INPUT "DESCRIPTION?";Desc$[1,20] 140 INPUT "UNIT COST?";Cost 150 INPUT "INITIAL QUANTITY?";Qty 160 PRINT #1,Record,29;Qty 170 PRINT #1,Record,13;Desc$ 180 PRINT #1,Record,25;Cost 190 PRINT #1,Record,1;Part$ 200 PRINT Part$,Desc$;TAB(35);Cost,Qty 210 NEXT Record 220 PRINT "DONE",LIN(5) 230 ENDLines 80 and 90 print headings for a table of input data. The FOR-NEXT loop inputs four items to be printed in each record, prints each item into subrecord within the currently-specified record, and outputs the data on the standard printer. Line 120 exits the loop when the operator enters DONE (upper or lower case) for a part number.
Notice that the word pointer parameter within each PRINT# specifies the first word for each subrecord.
These four items use only 64 bytes of each defined record; there are still 192 bytes available in each record for extra data.
It is important to know the exact length of each string variable printed using direct-word PRINT#. For example, lines 110 and 130 in the last program generate 20-character strings, regardless of the number of characters input. This, in turn, ensures that 20-character (20 byte) subrecords will be printed in lines 170 and 190. If the subscripts were not used in the INPUT statements, the first two subrecords printed in each logical record would vary in size, depending on the current string length.
The direct-word READ# statement reads numbers and strings into variables from a specified record, starting from a specified word.
As with serial and direct READ# statements, the variables into which you read data items do not need to have the same names from which you printed the data items on the record, but they must be the same type and the same order as the originals. When the data list is not used, the direct-word READ# resets the record pointer and word pointer to the specified record and word.
The previous example program opened a file to hold information on parts to be stored. The next program opens a file named ORDRPT (for order-point) and then searches the file STOCK for any item with a current quantity less than 10 (lines 120 through 150). When such an item is found, lines 160 through 180 read the part number, print the part number and quantity in file ORDRPT, and output the same data on the standard printer:
10 ! 20 ! PRINT ORDER-POINT REPORT 30 ! 40 CREATE "ORDRPT",1000 50 DIM Part$[20],Desc$[20] 60 ASSIGN #1 TO "STOCK" 70 ASSIGN #2 TO "ORDRPT" 80 INPUT "TODAY'S DATE:";Date$ 90 PRINTER IS 0 100 PRINT LIN(5),SPA(20),"PARTS TO REORDER ON ",Date$ 110 PRINT "PART NO. DESCRIPTION QTY. ON HAND",LIN(2) 120 FOR Part=1 TO 1000 130 READ #1,Part,29;Qty 140 IF Qty>=10 THEN Stokok 150 ! 10 or more items so no re-ordering needed. 160 Rd:READ #1,Part,1;Part$,Desc$ 170 PRINT #2;Part$,Qty 180 PRINT Part$,Desc$,Qty 190 Stokok:! 200 NEXT Part 210 PRINT "DONE",LIN(5) 220 ENDNotice that logical READ# (lines 130 and 160) enables you to read only the items required from a record, thus saving memory space and program execution time. Data is printed into file ORDRPT serially, since it need not be accessed separately.
As another example of direct-word access, the next program can be used to update the cost and quantity data for each record of file STOCK used in the previous programs. As in the first program, this program exits the input loop when the operator inputs "DONE" for a part number.
After the operator enters each set of data, the subroutine Search looks for the appropriate record in the file. After the record is found, lines 160 and 180 print the new cost and total quantity into that record. Line 190 then outputs the new data on the standard printer.
10 ! 20 ! UPDATE STOCK FILE 30 ! 40 DIM Part$[20], Desc$[20], Stock$[20] 50 ASSIGN #1 TO "STOCK" 60 INPUT "Today's Date: "; Date$ 70 PRINTER IS 0 80 PRINT LIN(5), SPA(15); "Parts Received On "; Date$ 90 PRINT "PART NO. COST QTY. RECEIVED QTY. ON HAND", LIN(1) 100 FOR Part=1 TO 1000 110 In:INPUT "PART NUMBER:";Part$[1,20] 120 IF UPC$(Part$[1,4])="DONE" THEN Done 130 INPUT "QUANTITY RECEIVED:"; Qty1 140 INPUT "UNIT COST:"; Cost1 150 GOTO Search 160 Pr:PRINT #1, Record, 25; Cost1 170 READ #1, Record, 29; Qty 180 PRINT #1,Part,29; Qty+Qty1 190 PRINT Part$, Cost1, Qty, Qty+Qty1 200 NEXT Part 210 Done: PRINT "DONE", LIN(5) 220 STOP 230 Search: ! Search for record to update 240 FOR Record=1 TO 1000 250 READ #1, Record,1;Stock$ 260 IF Stock$=Part$ then Pr 270 NEXT Record 280 PRINT "!!PART NOT ON FILE!!" 290 WAIT 2000 300 GOTO In 310 END