home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Student;
-
- {---------------------------------------------------------------}
- { PROGRAM TITLE: STUDENT version 2.0 }
- { WRITTEN BY: Raymond E. Penley }
- { DATE WRITTEN: Dec 18, 1982 }
- { }
- { INPUT/OUTPUT FILES: *** ACCESS METHOD *** }
- { STUDENT.NDX - Misc data <sequential> }
- { STUDENT.DAT - Name & Address <direct (random)> }
- { STUDENT.GDS - Grade data <sequential> }
- { }
- { COMMANDS: }
- { New student - Adds a new entry if file not filled. }
- { Find - Searches & displays a student }
- { Change - Allows changes on address/grades }
- { List - Displays data for all students }
- { Quit - Terminate program/close all files }
- { }
- { SUMMARY: }
- { Writes a name & address file and a grade file on all students.}
- { Also a file of misc. data; # of rcds on file and date file }
- { was last updated. }
- { }
- { 01/29/83 -- EXTENSIVE ERROR CORRECTING ADDED: }
- { 04/02/83 -- added vlength() by D. Cortesi }
- { }
- { NOTES: }
- { utility procedures from the Pascal/Z User's Group }
- { Library diskette. }
- {---------------------------------------------------------------}
-
-
- CONST
- MaxStudents = 200; { determines maximum # of data records in file }
- enter = 'ENTER NEW DATA OR PRESS RETURN TO KEEP PRESENT DATA';
- escape = 27; { ASCII escape character }
-
- TYPE
-
- {-------------------------------------------------------------}
- { create a binary search tree in memory to hold our index }
- {-------------------------------------------------------------}
-
- link = ^ip; { pointer to the binary tree }
- ip = RECORD { the binary tree record }
- item : integer; { KEY FIELD. student's id number }
- rcd : integer; { data file record pointer }
- left,right: link { pointers to left/right nodes }
- END;
-
- byte = 0..255;
- charset = SET OF CHAR;
- strng2 = string 2;
- strng5 = string 5;
- strng20 = string 20;
- strng = string 20;
-
-
- {-------------------------------------------------------------}
- { sturec - identifies the data to be stored for each student }
- {-------------------------------------------------------------}
-
- sturec = RECORD { field, type, length }
- id : integer; { id, n, 5 <KEY FIELD> }
- name, { name, c, 20 }
- street, { street, c, 20 }
- city : strng20;{ city, c, 20 }
- state : strng2; { state, c, 2 }
- zipcode: strng5 { zipcode,c, 5 }
- END;
- { total number of bytes = 77 per record.
- 72 bytes + 1 for each string }
-
-
- {-------------------------------------------------------------}
- { Allow for ten grades and the student ID. Please note that }
- { this may be changed to suit your particular requirements. }
- { NOTE: the enumerated type has been setup such that }
- { ORD(exam1) = 1. }
- {-------------------------------------------------------------}
-
- gradetype = ( id, { id field is link between all data files }
- exam1, { 1st exam grade }
- exam2, { 2nd exam grade }
- exam3, { 3rd exam grade }
- exam4, { 4th exam grade }
- exam5, { 5th exam grade }
- exam6, { 6th exam grade }
- exam7, { 7th exam grade }
- quiz1, { quiz 1 }
- quiz2, { quiz 2 }
- final); { final grade }
-
- {-------------------------------------------------------------}
- gradestore = array [gradetype] of integer;
-
- {-------------------------------------------------------------}
- StuGds = array [1..MaxStudents] of gradestore;
-
- {-------------------------------------------------------------}
- FTYPE = FILE OF StuRec;
-
- string0 = string 0;
- string255 = string 255;
-
- VAR
- bell : char; { console bell }
- command : char; { command character }
- console : TEXT; { direct output to console }
- date : packed array [1..8] of char; { date of last update }
- g : gradetype;
- Grades : StuGds;
- ioresult : boolean;
- listhead : link;
- more : boolean; { done processing flag }
- R : integer; { record pointer }
- rof : integer; { total Records On File }
- stucount : integer; { # of students in class }
- Student : StuRec; { A single student }
- StuFile : FTYPE; { name & address file }
- taken : integer; { # of tests taken thus far }
- updated : boolean; { flag for updated items }
-
- {$R-}{ range checking OFF }
-
- {-----------------------------------------------}
- { GENERAL PURPOSE UTILITIES }
- {-----------------------------------------------}
-
- {$iPRIMS.PZ }
-
-
- { pause - allows prgm to stop until ready to continue }
-
- PROCEDURE pause;
- VAR ch : char;
- BEGIN
- writeln;
- write ('Press any key to continue ');
- keyin(ch); writeln
- END{ pause };
-
-
- { ClearScreen - simple routine to clear the console device }
-
- PROCEDURE ClearScreen;
- VAR i: 1..25;
- BEGIN
- FOR i:=1 TO 25 DO writeln
- END{ ClearScreen };
-
-
- { Q - prints a text message and accepts only the characters }
- { passed via goodchars. Returns the result in uppercase. }
- { }
- { Q ( 'Enter "A", "B", or "C" -> ', ['A','B','C'], command ); }
- { }
- { REQUIRES: }
- { procedure keyin();external; }
- { function toupper():char;external; }
-
- PROCEDURE Q ( message: string255; goodchars: charset; VAR ch: char );
- CONST bell = 7; { ASCII bell char }
- VAR tch: char; { temp char }
- BEGIN
- write( message );
- REPEAT
- keyin(tch);
- ch := toupper(tch);
- IF ch IN goodchars
- THEN
- writeln (tch)
- ELSE
- write (chr(bell))
- UNTIL ch in goodchars
- END{ Q };
-
-
- { readint - input of an integer value between lower..upper. }
- { returns integer value and true if valid integer }
- { else returns a zero value and false. }
- { REQUIRES: }
- { function ivalue():integer; }
- { function vlength():integer;external; }
-
- FUNCTION readint ( VAR i: integer; lower,upper: integer ): boolean;
- VAR answer: strng20;
- BEGIN
- readint := true;
- readln(answer);
- IF vlength(answer) > 0 THEN BEGIN
- i := ivalue(answer,1);
- IF (i < lower) OR (upper < i ) THEN {do it again}
- readint := false;
- END
- END{ readint };
-
-
- {-----------------------------------------------}
- { PROGRAM SPECIFIC UTILITIES }
- {-----------------------------------------------}
-
- { gde - converts an integer to the enumerated type gradetype }
-
- FUNCTION gde ( exam: integer ): gradetype;
- BEGIN
- CASE exam OF
- 0: gde := id;
- 1: gde := exam1;
- 2: gde := exam2;
- 3: gde := exam3;
- 4: gde := exam4;
- 5: gde := exam5;
- 6: gde := exam6;
- 7: gde := exam7;
- 8: gde := quiz1;
- 9: gde := quiz2;
- 10: gde := final
- END
- END{ gde };
-
- {$R+}{ RANGE CHECKING ON }
-
-
- { insert - adds a node to the binary search tree, preserving the ordering }
-
- PROCEDURE insert( VAR node: link; ident, R: integer );
- BEGIN
- IF node=nil THEN BEGIN
- new(node); { create a new storage location }
- WITH node^ DO BEGIN
- left := nil;
- right := nil;
- item := ident; { store the student's id }
- rcd := R { store the location record pointer }
- END{with}
- END
- ELSE
- WITH node^ DO
- IF ident<item THEN
- insert ( left,ident,R )
- ELSE IF ident>item THEN
- insert ( right,ident,R )
- ELSE
- { DUPLICATE ENTRY }{ not handled }
- END{ insert };
-
-
- { search - returns a pointer to a node in the tree containing }
- { the given data, or nil if there is no such node. }
-
- FUNCTION search ( node: link; ident: integer ): link;
- BEGIN
- IF node=nil THEN
- search := nil
- ELSE
- WITH node^ DO
- IF ident<item THEN
- search := search(left,ident)
- ELSE IF ident>item THEN
- search := search(right,ident)
- ELSE
- search := node
- END{ search };
-
-
-
- PROCEDURE ListRange ( VAR first, last: integer );
- { RETURNS: }
- { one value -first = last }
- { all values -first = lower bound, last = highest bound }
- { a range of values -first/last = entered values }
- { ENTER with first = lower bound; last = uppermost bound. }
- VAR
- tch: char;
- t1,t2: integer;
- BEGIN
- t1 := first;
- t2 := last;
- writeln;
- Q( 'ENTER LIST RANGE: A(ll, O(ne, R(ange ->', ['A','O','R'], tch );
- CASE tch of
- 'A':
- BEGIN
- first := t1;
- last := t2
- END
- 'O':
- REPEAT
- write ( 'WHICH ONE? '); readln(first);
- last := first;
- UNTIL (first<=t2) or (first>=t1);
- 'R':
- REPEAT
- write ( 'Enter lower bound ->'); readln(first);
- write ( 'Enter upper bound ->'); readln(last)
- UNTIL first <= last
- end{CASE}
- END{ ListRange };
-
-
-
- { fread - reads the address file and sets the global record pointer }
-
- PROCEDURE fread ( VAR StuFile: FTYPE; VAR node: link );
- BEGIN
- R := node^.rcd; { returns the record pointer. }
- read ( StuFile:R, student ) { read student record R. }
- END{ fread };
-
-
-
- PROCEDURE ChangeAddress ( VAR student: sturec; VAR goodstatus: boolean );
- LABEL
- 1; { early exit }
- CONST
- ok = true;
- VAR
- answer: strng20;
- i : integer;
- node : link;
- valid : boolean;
-
- PROCEDURE disp ( message, value: string255 );
- BEGIN
- writeln;
- IF vlength(value) > 0 THEN BEGIN
- writeln ( message, value );
- write ( ' ':19 )
- END
- ELSE
- write ( message );
- END{ disp };
-
- BEGIN {ChangeAddress}
- goodstatus := ok;
- IF command = 'C' THEN BEGIN
- writeln;
- writeln ( enter )
- END;
- writeln;writeln;
- WITH student DO BEGIN
- IF id=0
- THEN
- setlength ( answer,0 )
- ELSE
- STR ( id,answer );
-
- { NOTE:
- do not allow ID to be changed after initial input }
- IF command = 'N' THEN BEGIN { adding New records }
- REPEAT
- disp ( 'ID Number ... ', answer )
- UNTIL readint ( id,1,9999 );
-
- node := search ( listhead,id ); { id already on file? }
- IF node<>nil THEN BEGIN { already on file }
- fread ( StuFile, node ); { read record for display }
- ClearScreen;
- writeln ( bell, id, ' already on file!');
- goodstatus := not ok;
- {EXIT}goto 1
- END
- END{IF command='N'...}
- ELSE
- writeln ( 'ID Number ... ', answer );
-
- disp ( 'Name ... ', name ); readln(answer);
- IF vlength(answer)>0 THEN
- name := answer;
-
- disp ( 'Street Address ... ', street ); readln(answer);
- IF vlength(answer)>0 THEN
- street := answer;
-
- disp ( 'City ... ', city ); readln(answer);
- IF vlength(answer)>0 THEN
- city := answer;
-
- disp ( 'State ... ', state ); readln(answer);
- IF vlength(answer)>0 THEN BEGIN
- state[1] := toupper ( answer[1] );
- state[2] := toupper ( answer[2] );
- setlength ( state,2 )
- END;
-
- REPEAT
- valid := true;
- disp ( 'Zip code ... ', zipcode ); readln(answer);
- IF vlength(answer)>0 THEN BEGIN
- zipcode := ' '; { insure no garbage in answer }
- IF isdigit(answer[1]) THEN { good chance is digit }
- FOR i:=1 TO 5 DO
- zipcode[i] := answer[i]
- ELSE BEGIN
- write(bell); valid := false
- END
- END
- UNTIL valid;
- END;
- updated := true;
- 1:{early exit}
- END{ ChangeAddress };
-
-
-
- PROCEDURE ChangeGrades ( VAR student: sturec );
- {NOTE:
- record pointer must be set before entry to ChangeGrades() }
- CONST
- low = 0; { lowest grade acceptable }
- high = 110; { highest grade acceptable <wow!>}
- VAR
- answer : strng20;
- first,last : gradetype;
- lower,upper : integer;
- BEGIN
- lower := 1;
- upper := taken;
- ListRange ( lower,upper );
- first := gde(lower);
- last := gde(upper);
- writeln;
- writeln ( enter );
- writeln;writeln;
- writeln ( 'STUDENT: ', student.name );
- writeln;
- FOR g:=first TO last DO BEGIN
- REPEAT
- write ( ord(g):3, grades[R,g]:6, ' ?' )
- UNTIL readint ( grades[R,g],low,high )
- END{FOR g}
- END{ ChangeGrades };
-
-
-
- PROCEDURE display ( VAR output: TEXT; VAR student: sturec );
- {NOTE:
- record pointer must be set before entry to display() }
- CONST
- width = 35;
- BEGIN
- writeln ( output );
- writeln ( output );
- WITH student DO BEGIN
- writeln ( output, 'STUDENT ID: ', id:1 );
- writeln ( output, name, ' ':width-vlength(name), street );
- writeln ( output, ' ':width, city, ', ', state, ' ', zipcode );
- writeln ( output, 'GRADES');
- writeln ( output, ' < first half year >< second half year >');
- FOR g:=exam1 TO gde(taken) DO
- write ( output, grades[R,g]:4 );
- writeln ( output );
- writeln ( output );
- writeln ( output )
- END
- END{ display };
-
-
-
- PROCEDURE MODIFY;
- VAR
- node : link;
- ch : char;
- goodstatus : boolean;
- BEGIN
- IF command='N' THEN { arrived here from ADD }
- command := 'C' { ... switch to CHANGE. }
- ELSE BEGIN
- writeln;
- REPEAT
- write ('Enter student id number ... ')
- UNTIL readint ( student.id,1,9999 )
- END;
-
- node := search ( listhead,student.id );
- IF node<>nil THEN BEGIN
- fread ( StuFile, node );
- CASE command of
- 'C':
- BEGIN {CHANGE}
- writeln;
- Q( 'Do you wish to change A(ddress, or G(rades? <escape=quit> ',
- [chr(escape),'A','G'], ch );
- if ord(ch)<>escape then begin
- CASE ch of
- 'A':
- ChangeAddress ( student,goodstatus );
- 'G':
- ChangeGrades ( student )
- END{CASE};
- display ( console,student );
- if ch='A' THEN { update address file }
- write ( StuFile:R, student )
- end
- END{ CHANGE };
- 'F':
- BEGIN {FIND}
- display ( console,student )
- END{ FIND }
- END{CASE}
- END
- ELSE
- writeln ( bell, student.id:1,' not on file!')
- END{ MODIFY };
-
-
-
- PROCEDURE ADD;
- VAR
- goodstatus: boolean;
- BEGIN
- IF rof >= MaxStudents THEN
- writeln ( 'Sorry can''t add file is full.' )
- ELSE BEGIN { OK to add more records }
- R := rof + 1; { temp set record pointer }
- WITH student DO BEGIN { initialize all fields to zero }
- id := 0;
- setlength ( name,0 );
- setlength ( street,0 );
- setlength ( city,0 );
- setlength ( state,0 );
- setlength ( zipcode,0 )
- END;
- writeln;
- writeln ( 'RECORD #', R:1 );
- ChangeAddress ( student,goodstatus );
- display ( console, student );
-
- IF goodstatus THEN BEGIN
- grades[R,id] := student.id; { update grades matrix }
- insert ( listhead,student.id,R );
- write ( StuFile:R, student ); { update address file }
- updated := true; { flag we updated the file }
- rof := R; { increment records on file }
- stucount := rof; { and student count }
- { move right into edit mode...change address/grades }
- MODIFY
- END{IF goodstatus then...};
- pause
- END{ELSE}
- END{ ADD };
-
-
-
- { list - lists ALL records on file }
-
- PROCEDURE LIST;
- VAR
- output : TEXT;
-
- { printlist - writes the entire tree recursively }
- PROCEDURE PrintList ( node: link );
- LABEL 1;
- BEGIN
- IF node<>nil THEN
- WITH node^ DO BEGIN
- PrintList (left);
- fread ( StuFile, node ); { read address file }
- display ( output, student );
- { test the keyboard and abort on any keypress }
- IF conchar<>0 THEN BEGIN {ABORT}
- writeln;writeln(chr(7);'ABORTED');goto 1
- END;
- IF command<>'P' THEN pause;
- PrintList ( right )
- END{with};
- 1:{abort}
- END{ PrintList };
-
- BEGIN
- writeln;
- Q('Output to C(onsole or P(rinter? <escape=quit> ',
- [chr(escape),'C','P'], command );
- IF ord(command)=escape THEN
- {all done}
- ELSE BEGIN
- CASE command OF
- 'P': { direct output to the list device }
- REWRITE( 'LST:',output );
- 'C': { direct output to the console device }
- REWRITE( 'CON:',output )
- end{CASE};
- PrintList(listhead)
- END
- END{ LIST }{ CLOSE(output); };
-
-
-
- { report - generates totals and prints a formatted report on each student }
-
- PROCEDURE report;
- LABEL
- 1; {abort}
- CONST
- fw = 6;
- TYPE
- atype = (avg,total);
- VAR
- a,rr : integer;
- aborted : boolean;
- accum : array [avg..total,gradetype] of integer;
- first,g,
- last : gradetype;
- output : TEXT;
-
-
- PROCEDURE PrintClass ( node: link );
- LABEL
- 2; {abort}
- BEGIN
- IF node<>nil THEN
- WITH node^ DO BEGIN
- PrintClass (left);
- R := rcd;
- rr := rr + 1;
- { output line consists of: line #, student id #, grades }
- write ( output, rr:3, grades[R,id]:5, ' ' );
- a := 0; { "a" = grade accumulator }
- FOR g:=first TO last DO BEGIN
- write ( output,grades[R,g]:fw );
- a := a + grades[R,g];
- accum[total,g] := accum[total,g] + grades[R,g]
- END{FOR g};
- { print the rounded average of this student's grades }
- writeln (output, ' ', round(a/taken):fw );
-
- { test the keyboard and abort on any keypress }
- IF conchar<>0 THEN BEGIN {ABORT}
- aborted := true;
- writeln;writeln(chr(7);'ABORTED');goto 2
- END;
- PrintClass ( right )
- END{with};
- 2:{abort}
- END{ PrintClass };
-
- BEGIN{ report }
- writeln;
- Q('Output to C(onsole or P(rinter? <escape=quit> ',
- [chr(escape),'C','P'], command );
- IF ord(command)=escape THEN
- goto 1; {all done}
- CASE command OF
- 'P': { direct output to the list device }
- REWRITE( 'LST:',output );
- 'C': { direct output to the console device }
- REWRITE( 'CON:',output )
- END{CASE};
-
- first := exam1; { first = 1st exam grade, last = last exam taken }
- last := gde(taken);
-
- {REPORT LINE 1}
- writeln ( output );
- write(output,' STUDENT ');
- FOR g:=first TO last DO
- IF ord(g)=1
- then write(output,' EXAMS')
- else write(output,' ');
- writeln(output,' AVERAGE');
-
- {REPORT LINE 2}
- write ( output,'======== ' );
- FOR g:=first TO last DO BEGIN
- write( output,ord(g):fw );
- accum[total,g] := 0 { zero total accumulator }
- END;
- writeln ( output,' =======' );
-
- {REPORT LINE 3...n}
- rr := 0;
- aborted := false;
- PrintClass(listhead);
- if aborted then goto 1;
- write ( output,' ' );{ 10 spaces }
- FOR g:=first TO last DO BEGIN
- { compute the average for all the student's grades }
- accum[avg,g] := accum[total,g] DIV stucount;
- { underline each column }
- write(output,' ---');
- END;
- writeln (output);
-
- {REPORT SUMMATION LINE...}
- writeln ( ' CLASS' );
- write ( ' AVERAGE: ');
- FOR g:=first TO last DO
- write ( output,accum[avg,g]:fw );
- writeln ( output );
- writeln ( output );
- 1:{abort}
- END{ report }{ CLOSE(output); };
-
-
-
- PROCEDURE STATS;
- VAR
- answer : strng20;
- valid : boolean;
- BEGIN
- writeln;
- writeln ( 'MAX STUDENTS ALLOWED ... ', MaxStudents:3 );
- writeln ( 'NUMBER OF STUDENTS ..... ', stucount:3 );
- REPEAT
- write ('NUMBER OF TESTS ........ ', taken:3,' ?' );
- readln ( answer );
- IF vlength(answer)>0 THEN
- taken := ivalue( answer,1 );
- valid := (taken>=0)
- UNTIL valid
- END{ STATS };
-
-
-
- PROCEDURE fclose;
- VAR
- StuGrades: FILE OF gradestore; { grade data on each student }
- StuNdx : TEXT; { index file }
- BEGIN
- { OPEN 'STUDENT.NDX' for WRITE assign StuNdx }
- rewrite('STUDENT.NDX',StuNdx);
- writeln ( StuNdx, rof );
- writeln ( StuNdx, date );
- writeln ( StuNdx, stucount ); { # of students in class }
- writeln ( StuNdx, taken ); { # of tests taken thus far }
-
- { OPEN 'STUDENT.GDS' for WRITE assign StuGrades }
- rewrite('STUDENT.GDS',StuGrades);
- FOR R:=1 TO rof DO
- write ( StuGrades, grades[R] )
- END{ fclose }{ CLOSE(StuNdx); CLOSE(StuGrades); };
-
-
-
- PROCEDURE Initialize;
- VAR
- i,rr : integer;
- ch : char;
- StuGrades: FILE OF gradestore; { grade data on each student }
- StuNdx : TEXT; { index file }
- BEGIN
- ClearScreen;
- writeln ( ' ':32, 'STUDENT SYSTEM');
- writeln;
- writeln;
- bell := chr(7);
- listhead := nil; { make the list empty }
- updated := false; { say file has not been updated }
-
- { insure that all cells in grades matrix are 0 }
- FOR g:=id TO final DO
- grades[1,g] := 0;
- FOR rr:=2 TO MaxStudents DO
- grades[rr] := grades[1];
-
- { OPEN 'CON:' for WRITE assign console } {open files=1}
- rewrite('CON:',console);
-
- { OPEN 'STUDENT.NDX' for READ assign StuNdx } {open files=2}
- reset('STUDENT.NDX',StuNdx);
-
- IF eof(StuNdx) THEN BEGIN {create all files}
- writeln ( 'Please standby while I create data files ...' );
- { OPEN 'STUDENT.NDX' for WRITE assign StuNdx } {open files=2}
- rewrite('STUDENT.NDX',StuNdx);
- { OPEN 'STUDENT.DAT' for WRITE assign StuFile } {open files=3}
- rewrite('STUDENT.DAT',StuFile);
- { OPEN 'STUDENT.GDS' for WRITE assign StuGrades } {open files=4}
- rewrite('STUDENT.GDS',StuGrades);
-
- rof := 0;
- stucount := 0;
- taken := 10; { setup to 10 then can lower at any time }
- date := 'MM/DD/YY'
- END
- ELSE BEGIN { finish opening files and read record count }
- { OPEN 'STUDENT.DAT' for READ assign StuFile } {open files=3}
- reset('STUDENT.DAT',StuFile);
- { OPEN 'STUDENT.GDS' for READ assign StuGrades } {open files=4}
- reset('STUDENT.GDS',StuGrades);
-
- readln ( StuNdx, rof );
- readln ( StuNdx, date );
- readln ( StuNdx, stucount ); { # of students in class }
- readln ( StuNdx, taken ); { # of tests taken thus far }
- writeln;
- FOR rr:=1 TO rof DO BEGIN
- write( chr(13), 'RECORD #', rr:1 );
- read ( StuGrades, grades[rr] );
- read ( StuFile:rr,student ); { create the B-tree in memory }
- insert ( listhead,student.id,rr ){ INDEX ON student.id }
- END;
- writeln
- END;
-
- IF rof>0 THEN BEGIN
- writeln;
- writeln ( 'There are ',rof:1,' records on file as of ', date )
- END;
- writeln;
- write ( 'ENTER TODAY''S DATE <MM/DD/YY> ->');
- keyin(ch);
- if ord(ch)=13 then
- {accept date given}
- else begin
- date[1] := ch;
- write(ch);
- FOR i:=2 TO 8 DO BEGIN
- IF (i=3) or (i=6)
- THEN ch := '/'
- ELSE keyin(ch);
- write(ch);
- date[i] := ch
- END;
- end;
- writeln
- END{ Initialize }{ CLOSE(StuNdx); CLOSE(StuGrades); }; {open files=2}
-
-
-
- BEGIN (*** MAIN PROGRAM ***)
- Initialize;
- more := true;
- WHILE more DO BEGIN
- writeln;
- Q('N(ew student, F(ind, C(hange, R(eport, L(ist, S(tats, Q(uit ...?',
- ['N','C','F','R','L','S','Q'], command );
- CASE command of
- 'N':
- ADD;
- 'C','F':
- MODIFY;
- 'R':
- report;
- 'L':
- LIST;
- 'S':
- STATS;
- 'Q':
- more := false
- end{CASE}
- END{while};
- IF updated THEN fclose
- END.
-
-