home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Learn Pascal in a Three Days (2nd Ed.)
(Publisher: Wordware Publishing, Inc.)
Author(s):
ISBN: 1556225679
Publication Date: 07/01/97

Bookmark It

Search this book:
 
Previous Table of Contents Next


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:

1.  A call to the “SearchList” procedure is made before entering the data of a new employer. The social security number is checked to see if it originally exists. If it does, no data are entered, and the proper message is issued.
2.  The “DelRecord” procedure is added.
3.  The “UpdateRec” procedure is added.
4.  The “SearchList” procedure is used to reject any operation (e.g., delete, update, or display) if the SSN is not found.
{ -------------------------- 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.


Previous Table of Contents Next


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.