|
To access the contents, click the chapter and section titles.
Learn Pascal in a Three Days (2nd Ed.)
Because the PreviousPointer follows the CurrentPointer and its value is expected to change, it has to be preceded by the keyword VAR. The following is the DelRecord procedure: { ----------------------- Procedure DelRecord ------------------------ } PROCEDURE DelRecord(VAR FirstPointer:ListPointer); VAR CurrentPointer, PreviousPointer:ListPointer; Found :BOOLEAN; SSNumber: SSNstring; BEGIN Found := FALSE; WRITELN(Separator); WRITE('Enter the SSN of the employee to be removed:'); READLN(SSNumber); SearchList(FirstPointer, CurrentPointer, PreviousPointer, SSNumber, Found); IF NOT Found THEN WRITELN('SSN: ', SSNumber, ' Not Found') ELSE BEGIN IF PreviousPointer = NIL THEN { The node to be deleted is the first node. } FirstPointer:= FirstPointer^.NextField ELSE { The node to be deleted has a predecessor. } PreviousPointer^.NextField:= CurrentPointer^.NextField; DISPOSE(CurrentPointer); WRITELN('The record has been deleted from the list.') END; WRITE('Hit any key to continue...'); READLN END; The changes made on the SearchList procedure will affect other procedures. Any call to the SearchList must include the new pointer parameter PreviousPointer as shown in the call below: SearchList(FirstPointer, CurrentPointer, PreviousPointer, SSNumber, Found); In the previous program (10-14.pas) the DisplayRec procedure calls SearchList using two pointer parameters only. This is obvious because PreviousPointer is not used in the DisplayRec procedure. In order to incorporate the new Search List procedure into the program, the calls to the SearchList must be modified. In the procedure DisplayRec, you may declare a dummy pointer which has no work to do except being passed as a parameter to the search procedure. This is an example of the new call: SearchList(FirstPointer, CurrentPointer, DummyPointer, SSNumber, Found); In the following program, the employee database is almost completed. These are the main features of the program:
{ -------------------------- figure 11-17 ---------------------------- } PROGRAM LinkedListDB(INPUT, OUTPUT, MyListFile); CONST FileName = 'emplist.bin'; Header = '------------- Main Menu --------------'; Separator = '--------------------------------------'; TYPE {Declaration of data type } SSNstring = STRING[11]; DataRecord = RECORD ID :STRING[5]; Name, Position :STRING[20]; SSN :SSNstring; Rate :REAL END; {Declaration of the list } ListPointer = ^ListRecord; ListRecord = RECORD DataField :DataRecord; NextField :ListPointer END; EmpFile = FILE OF DataRecord; VAR FirstPointer :ListPointer; MyListFile :EmpFile; EmpRecord :DataRecord; { ----------------------- Procedure SearchList ----------------------- } { This procedure searches the linked list for an employee's SSN. If found, the value of the boolean flag "Found" becomes TRUE} PROCEDURE SearchList(FirstPointer :ListPointer; VAR CurrentPointer :ListPointer; VAR PreviousPointer :ListPointer; SSNumber :SSNstring; VAR Found :BOOLEAN); BEGIN PreviousPointer := NIL; CurrentPointer := FirstPointer; WHILE (CurrentPointer <> NIL) AND (NOT Found) DO IF CurrentPointer^.DataField.SSN = SSNumber THEN Found := TRUE ELSE BEGIN PreviousPointer := CurrentPointer; CurrentPointer := CurrentPointer^.NextField END END; { ----------------------- Procedure BuildList ------------------------ } PROCEDURE BuildList(VAR FirstPointer:ListPointer; DataItem :DataRecord); { This procedure builds the liked list, or adds nodes to it.} {Note: The FirstPointer is passed using the VAR keyword as it will be updated by this procedure } VAR ToolPointer :ListPointer; BEGIN NEW(ToolPointer); ToolPointer^.DataField := DataItem; ToolPointer^.NextField := FirstPointer; FirstPointer := ToolPointer END; { ----------------------- Procedure ReadList ------------------------- } PROCEDURE ReadList(FirstPointer:ListPointer); { This procedure reads and displays the contents of the list } VAR CurrentPointer :ListPointer; BEGIN CurrentPointer := FirstPointer; WHILE CurrentPointer <> NIL DO BEGIN WITH CurrentPointer^.DataField DO BEGIN WRITE(ID :7); WRITE(Name :22); WRITE(Position :22); WRITE(SSN :13); WRITELN(' $',Rate :0:2) END; CurrentPointer:= CurrentPointer^.NextField END; WRITELN END; { ---------------------- Procedure DelRecord ------------------------- } PROCEDURE DelRecord(VAR FirstPointer:ListPointer); { This procedure deletes a node from the list. If the node to be deleted is the first node. The "FirstPointer" is moved to the next node; otherwise, the pointer field of the previous node is updated to point to the next node. In both cases the "CurrentPointer" is disposed. } VAR CurrentPointer, PreviousPointer:ListPointer; Found:BOOLEAN; SSNumber: SSNstring; BEGIN Found:= FALSE; WRITELN(Separator); WRITE('Enter the SSN of the employee to be removed:'); READLN(SSNumber); SearchList(FirstPointer, CurrentPointer, PreviousPointer, SSNumber, Found); IF NOT Found THEN WRITELN('SSN: ', SSNumber, ' Not Found') ELSE BEGIN IF PreviousPointer = NIL THEN { The node to be deleted is the first node. } FirstPointer := FirstPointer^.NextField ELSE { The node to be deleted has a predecessor. } PreviousPointer^.NextField:= CurrentPointer^.NextField; DISPOSE(CurrentPointer); WRITELN('The record has been deleted from the list.') END; WRITE('Hit any key to continue...'); READLN END; { ------------------------ Procedure GetData ------------------------- } PROCEDURE GetData(VAR FirstPointer:ListPointer); { This procedure receives the employee data from the keyboard, and passes the record information to the procedure "BuildList" to be added to the linked list } VAR CurrentPointer, DummyPointer:ListPointer; Item :DataRecord; SSNumber: SSNstring; Found :BOOLEAN; BEGIN Found := FALSE; WRITE('Please enter the SSN of the employee: '); READLN(SSNumber); SearchList(FirstPointer, CurrentPointer, DummyPointer, SSNumber, Found); IF NOT Found THEN BEGIN WRITELN('Please enter the employee information:'); WITH Item DO BEGIN SSN := SSNumber; WRITE('ID: '); READLN(ID); WRITE('Name: '); READLN(Name); WRITE('Position: '); READLN(Position); WRITE('Rate: '); READLN(Rate); WRITELN(Separator) END; BuildList(FirstPointer, Item); WRITELN('The employee has been added to the list.') END ELSE WRITELN('The SSN: ', SSNumber, ' is already in the list.'); WRITE('Hit any key to continue...'); READLN END; { ----------------------- Procedure DisplayItAll --------------------- } PROCEDURE DisplayItAll(FirstPointer:ListPointer); { This procedures displays the headers of the fields in the proper format and calls the procedure "ReadList" to display the contents of the list } BEGIN WRITELN(Separator); WRITELN('The contents of the list: '); WRITELN('ID':7, 'Name':22, 'Position':22, 'SSN':13, 'Rate':7); WRITELN; ReadList(FirstPointer); WRITE('Hit any key to continue...'); READLN END; { ----------------------- Procedure DisplayRec ----------------------- } PROCEDURE DisplayRec(FirstPointer:ListPointer); { This procedure displays the information for a specific employee. It calls the procedure "SearchList" to search the list using the Social Security Number of the employee.} VAR CurrentPointer, DummyPointer:ListPointer; SSNumber :SSNstring; Found :BOOLEAN; { Note: The "DummyPointer" is used to call the "SearchList" procedure (which takes three pointers as parameters), but this pointer is not required in this procedure. } BEGIN Found := FALSE; WRITELN(Separator); WRITE('Enter the SSN of the employee:'); READLN(SSNumber); SearchList(FirstPointer, CurrentPointer, DummyPointer, SSNumber, Found); IF NOT Found THEN WRITELN('SSN: ', SSNumber, ' Not Found') ELSE WITH CurrentPointer^.DataField DO BEGIN WRITELN('ID: ',ID); WRITELN('Name: ',Name); WRITELN('Position: ', Position); WRITELN('Social Security Number: ', SSN); WRITELN('Hourly Rate: $', Rate:2:2) END; WRITE('Hit any key to continue...'); READLN END; { ----------------------- Procedure UpdateRec ------------------------ } PROCEDURE UpdateRec(FirstPointer:ListPointer); { This procedure updates record information for a specific employee. It calls the procedure "SearchList" to search the list using the Social Security Number of the employee. The new information is accepted from the user, otherwise a message "not found" is issued.} VAR CurrentPointer, DummyPointer:ListPointer; SSNumber :SSNstring; Found :BOOLEAN; { Note: The "DummyPointer" is used to call the "SearchList" procedure (which takes three pointers as parameters), but this pointer is not required in this procedure. } BEGIN Found := FALSE; WRITELN(Separator); WRITE('Enter the SSN of the employee:'); READLN(SSNumber); SearchList(FirstPointer, CurrentPointer, DummyPointer, SSNumber, Found); IF NOT Found THEN WRITELN('SSN: ', SSNumber, ' Not Found') ELSE WITH CurrentPointer^.DataField DO BEGIN WRITELN('Please enter the now information for', ' the employee (SSN: ', SSNumber,'):'); WRITE('ID: '); READLN(ID); WRITE('Name: '); READLN(Name); WRITE('Position: '); READLN(Position); WRITE('Hourly Rate: '); READLN(Rate); WRITELN('Record updated.') END; WRITE('Hit any key to continue...'); READLN END; { ----------------------- Procedure SaveList ------------------------- } PROCEDURE SaveList(FirstPointer:ListPointer; VAR MyListFile: EmpFile); {This procedure saves the data fields in the linked list to a file of the type RECORD. } VAR CurrentPointer:ListPointer; BEGIN ASSIGN(MyListFile, FileName); REWRITE(MyListFile); CurrentPointer := FirstPointer; WHILE CurrentPointer <> NIL DO BEGIN WRITE(MyListFile, CurrentPointer^.DataField); CurrentPointer := CurrentPointer^.NextField END; CLOSE(MyListFile); WRITELN('The list has been saved to the file.'); WRITE('Hit any key to continue...'); READLN END; { ----------------------- Procedure ReadFile ------------------------- } PROCEDURE ReadFile(VAR FirstPointer:ListPointer; VAR MyListFile: EmpFile); {This procedure reads data from the file "emplist.bin" and adds the data to the linked list. } VAR Item :DataRecord; BEGIN ASSIGN(MyListFile, FileName); RESET(MyListFile); WHILE NOT EOF (MyListFile) DO BEGIN READ(MyListFile, Item); BuildList(FirstPointer, Item); END; CLOSE(MyListFile); WRITELN('The employee list is ready in memory.'); WRITE('Hit any key to continue...'); READLN END; { ------------------------- Procedure Menu --------------------------- } PROCEDURE Menu; VAR Option:INTEGER; BEGIN WRITELN(Header); WRITELN('1. Add records to the list.'); WRITELN('2. Display the whole list.'); WRITELN('3. Display an employee record.'); WRITELN('4. Add records from file.'); WRITELN('5. Save the list to a file.'); WRITELN('6. Delete a record.'); WRITELN('7. Update a record.'); WRITELN('8. Exit.'); WRITELN(Separator); WRITE('Make a choice and press a number: '); READLN(Option); CASE Option OF 1: GetData(FirstPointer); 2: DisplayItAll(FirstPointer); 3: DisplayRec(FirstPointer); 4: ReadFile(FirstPointer, MyListFile); 5: SaveList(FirstPointer, MyListFile); 6: DelRecord(FirstPointer); 7: UpdateRec(FirstPointer); 8: Exit END; Menu END; { --------------------------- Main Program --------------------------- } BEGIN { Initialize an empty List } FirstPointer := NIL; menu END.
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement. |