darentan
asked on
Pointer Linklist record sorting
Hi, below is my program , i thinking of sort all the records via using the datarecord.year in ascending order
Program Books;
Uses Crt; {Use because of clear screen command used}
Type
DataRecord = Record
Bookname : String [50];
Author : String [30];
Publisher : String [30];
Year : Integer ;
Size : String [ 2];
Pages : Integer ;
Price : Real ;
Intro : String [30];
End; {end of record}
ListPointer = ^ListRecord;
ListRecord = Record
DataField : DataRecord; {data field type}
NextField : ListPointer {pointer address to next book}
End;
Var
FirstPointer : ListPointer;
{************************* ********** ********** ********** ********** *******
Procedure Name : Initialise
Input : Invoke by main program to do initialise all the pointers.
Task : Initialise and set the relationship for current, firstpointer
,nextfield and clear data that may exist in currentpointer
Output: It will reset and clear all data present in the records/pointers.
************************** ********** ********** ********** ********** ******* }
Procedure Initialise;
Var
Input : Char;
CurrentPointer : ListPointer;
Begin
While Assigned (FirstPointer) Do {Test if a pointer variable is nil}
Begin
CurrentPointer := FirstPointer; {Force current pointer to first node}
FirstPointer := FirstPointer^. NextField;
Dispose (CurrentPointer); {Once first node deleted, rest also}
End;
WriteLn ('The bookcase is Empty but ready for books.');
Repeat
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
Until Input = 'M'
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Addbook
Input : Invoke by main program to do capturing of all books.
Task : Accept user input on the books and save it to the record.
Output: Record will hold all the data and store into memory
************************** ********** ********** ********** ********** ******* }
Procedure Addbook;
Var
CurrentPointer, TempPointer : ListPointer;
Continue : Char;
Begin
Repeat
New (CurrentPointer); {Creates a new dynamic variable}
With CurrentPointer^. DataField Do
Begin
WriteLn;
WriteLn ('Please input details including');
Write ('Bookname : '); ReadLn (Bookname );
Write ('Author : '); ReadLn (Author );
Write ('Publisher : '); ReadLn (Publisher);
Write ('Publication year : '); ReadLn (Year );
Write ('Size : '); ReadLn (Size );
Write ('Pages : '); ReadLn (Pages );
Write ('Sale price : '); ReadLn (Price );
Write ('Brief introduction : '); ReadLn (Intro );
End;
CurrentPointer^. NextField := Nil; {Ensure & set next node to nil}
If FirstPointer = Nil Then {Is first node empty? }
FirstPointer := CurrentPointer {Setting the first node }
Else
Begin
TempPointer := FirstPointer;
While TempPointer^. NextField <> Nil Do
TempPointer := TempPointer^. NextField; {Set next node}
TempPointer^. NextField := CurrentPointer;
End;
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
While (Continue <> 'Y') And (Continue <> 'N') Do
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
Delay (300);
End;
Until Continue = 'N';
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : DelRecord
Input : Invoke by readlist procedure to delete current record.
Task : Delete current record from record and.
Output: Current book record will be remove from the main book record.
************************** ********** ********** ********** ********** ******* }
Procedure DelRecord (Var RecordToDelete : ListPointer);
Var
CurrentPointer, PreviousPointer : ListPointer;
Begin
CurrentPointer := FirstPointer;
While (CurrentPointer <> RecordToDelete) And (CurrentPointer <> Nil) Do
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField;
End;
If CurrentPointer <> Nil Then { NIL would mean "not found" }
Begin
If CurrentPointer = FirstPointer Then { Is it the first Record? }
FirstPointer := CurrentPointer^. NextField
Else
PreviousPointer^. NextField := CurrentPointer^. NextField;
End;
RecordToDelete := CurrentPointer^. NextField;
Dispose (CurrentPointer);
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Readlist
Input : Invoke by main_menu procedure to display all the records.
Task : Read and display the contents of the list.
Output: Display all the books informations in the record, one at a time.
************************** ********** ********** ********** ********** ******* }
Procedure ReadList;
Var
CurrentPointer : ListPointer;
Purchase : Char;
ViewNext : Char;
Begin
CurrentPointer := FirstPointer;
WriteLn ('The contents of the list: ');
If currentpointer = Nil Then
Begin
WriteLn;
WriteLn ('The bookcase is empty');
Delay (800);
End;
While CurrentPointer <> Nil Do
Begin
With CurrentPointer^. DataField Do
Begin
WriteLn;
Write ('Bookname : '); WriteLn (bookname);
Write ('Author : '); WriteLn (author);
Write ('Publisher : '); WriteLn (publisher);
Write ('Publication year : '); WriteLn (Year);
Write ('Size : '); WriteLn (Size);
Write ('Pages : '); WriteLn (pages);
Write ('Sale price : '); WriteLn ('$', price : 4 : 2);
Write ('Brief introduction : '); WriteLn (intro);
Write ('Purchase (y/n)? : '); ReadLn (purchase);
Repeat
purchase := UpCase (purchase);
If Not (purchase In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Purchase (y/n)? : '); ReadLn (purchase);
End;
Until (purchase = 'N') Or (purchase = 'Y');
If purchase = 'Y' Then
Delrecord (currentpointer) {This currentpointer record will be}
Else {pass to the delrecord procedure }
CurrentPointer := CurrentPointer^. NextField;
End;
Write ('View the next (y/n)? : '); ReadLn (viewnext);
Repeat
viewnext := UpCase (viewnext);
If Not (viewnext In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('View the next (y/n)? : '); ReadLn (viewnext);
End;
Until (viewnext = 'N') Or (viewnext = 'Y');
If viewnext = 'Y' Then
Begin
If currentpointer = Nil Then
currentpointer := firstpointer;
Continue;
End
Else
If viewnext = 'N' Then
CurrentPointer := FirstPointer;
Exit;
End;
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Sold
Input : Invoke by main menu of the program.
Task : It keep track of all the book purchased during the view book
procedure where user have the option to purchase the book.
Output: Display all the book purchased by the user.
************************** ********** ********** ********** ********** ******* }
Procedure Sold;
Begin
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Search
Input : Invoke by main menu of the program.
Task : Using year field in the record, the program will search through
all the records and display results that match the query.
Output: Display all the book based on the year input by the user.
************************** ********** ********** ********** ********** ******* }
Procedure Search;
Var
found : Boolean;
bk_year : Integer;
PreviousPointer: ListPointer;
CurrentPointer : ListPointer;
Again : Char;
Input : Char;
Begin
Repeat
Repeat
Found := False;
Write ('Please input the year of the book (1900-2000) > '); ReadLn (bk_year);
Begin
PreviousPointer := Nil;
CurrentPointer := FirstPointer;
While (CurrentPointer <> Nil) And (Not Found) Do
If CurrentPointer^. DataField. Year = bk_year Then
Found := True
Else
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField
End
End;
If Not Found Then
Begin
WriteLn ('Sorry no book published in ', bk_year, ' is for sale');
Repeat
Write ('Press "y" to try again : '); ReadLn (again);
If Not (again In ['Y', 'y'] ) Then
Begin
WriteLn ('Press "y" to try again : ');
End;
Until (again In ['y', 'Y'] );
End
Else
With CurrentPointer^. DataField Do
Begin
WriteLn;
Write ('Bookname : '); WriteLn (bookname);
Write ('Author : '); WriteLn (author);
Write ('Publisher : '); WriteLn (publisher);
Write ('Publication year : '); WriteLn (Year);
Write ('Size : '); WriteLn (Size);
Write ('Pages : '); WriteLn (pages);
Write ('Sale price : '); WriteLn ('$', price : 4 : 2);
Write ('Brief introduction : '); WriteLn (intro);
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
End;
Until found = True;
Until (Input = 'M');
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Main_Menu
Input : Invoke by main body of the program.
Task : It display to use the choices he can do, input books records,
reset book records or view and purchase the books.
Output: Display the main menu of the program and awaits user inputs.
************************** ********** ********** ********** ********** ******* }
Procedure Main_Menu;
Var
Option : Char ;
Begin
Repeat
ClrScr;
WriteLn ('Books for Sale');
WriteLn ('--------------');
WriteLn ('1. View books');
WriteLn ('2. Initialise bookcase');
WriteLn ('3. Add Books');
WriteLn ('4. Display the books sold');
WriteLn ('5. Search a book');
WriteLn ('0. Quit');
Write ('Enter your choice > '); ReadLn (Option);
Case Option Of
'1': Readlist;
'2': Initialise;
'3': Addbook;
'4': Sold;
'5': Search;
'0': Exit
Else
Write ('Invalid Choice, Please enter 1, 2, 3 or 0');
Delay (300);
ClrScr;
End;
Until Option = '0';
End;
{************************* ********** ********** ********** ********** ****}
{Main Body of the Program}
{************************* ********** ********** ********** ********** ****}
Begin
ClrScr; {Ensure the program start in a fresh new screen}
Main_menu
End.
Program Books;
Uses Crt; {Use because of clear screen command used}
Type
DataRecord = Record
Bookname : String [50];
Author : String [30];
Publisher : String [30];
Year : Integer ;
Size : String [ 2];
Pages : Integer ;
Price : Real ;
Intro : String [30];
End; {end of record}
ListPointer = ^ListRecord;
ListRecord = Record
DataField : DataRecord; {data field type}
NextField : ListPointer {pointer address to next book}
End;
Var
FirstPointer : ListPointer;
{*************************
Procedure Name : Initialise
Input : Invoke by main program to do initialise all the pointers.
Task : Initialise and set the relationship for current, firstpointer
,nextfield and clear data that may exist in currentpointer
Output: It will reset and clear all data present in the records/pointers.
**************************
Procedure Initialise;
Var
Input : Char;
CurrentPointer : ListPointer;
Begin
While Assigned (FirstPointer) Do {Test if a pointer variable is nil}
Begin
CurrentPointer := FirstPointer; {Force current pointer to first node}
FirstPointer := FirstPointer^. NextField;
Dispose (CurrentPointer); {Once first node deleted, rest also}
End;
WriteLn ('The bookcase is Empty but ready for books.');
Repeat
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
Until Input = 'M'
End;
{*************************
Procedure Name : Addbook
Input : Invoke by main program to do capturing of all books.
Task : Accept user input on the books and save it to the record.
Output: Record will hold all the data and store into memory
**************************
Procedure Addbook;
Var
CurrentPointer, TempPointer : ListPointer;
Continue : Char;
Begin
Repeat
New (CurrentPointer); {Creates a new dynamic variable}
With CurrentPointer^. DataField Do
Begin
WriteLn;
WriteLn ('Please input details including');
Write ('Bookname : '); ReadLn (Bookname );
Write ('Author : '); ReadLn (Author );
Write ('Publisher : '); ReadLn (Publisher);
Write ('Publication year : '); ReadLn (Year );
Write ('Size : '); ReadLn (Size );
Write ('Pages : '); ReadLn (Pages );
Write ('Sale price : '); ReadLn (Price );
Write ('Brief introduction : '); ReadLn (Intro );
End;
CurrentPointer^. NextField := Nil; {Ensure & set next node to nil}
If FirstPointer = Nil Then {Is first node empty? }
FirstPointer := CurrentPointer {Setting the first node }
Else
Begin
TempPointer := FirstPointer;
While TempPointer^. NextField <> Nil Do
TempPointer := TempPointer^. NextField; {Set next node}
TempPointer^. NextField := CurrentPointer;
End;
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
While (Continue <> 'Y') And (Continue <> 'N') Do
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
Delay (300);
End;
Until Continue = 'N';
End;
{*************************
Procedure Name : DelRecord
Input : Invoke by readlist procedure to delete current record.
Task : Delete current record from record and.
Output: Current book record will be remove from the main book record.
**************************
Procedure DelRecord (Var RecordToDelete : ListPointer);
Var
CurrentPointer, PreviousPointer : ListPointer;
Begin
CurrentPointer := FirstPointer;
While (CurrentPointer <> RecordToDelete) And (CurrentPointer <> Nil) Do
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField;
End;
If CurrentPointer <> Nil Then { NIL would mean "not found" }
Begin
If CurrentPointer = FirstPointer Then { Is it the first Record? }
FirstPointer := CurrentPointer^. NextField
Else
PreviousPointer^. NextField := CurrentPointer^. NextField;
End;
RecordToDelete := CurrentPointer^. NextField;
Dispose (CurrentPointer);
End;
{*************************
Procedure Name : Readlist
Input : Invoke by main_menu procedure to display all the records.
Task : Read and display the contents of the list.
Output: Display all the books informations in the record, one at a time.
**************************
Procedure ReadList;
Var
CurrentPointer : ListPointer;
Purchase : Char;
ViewNext : Char;
Begin
CurrentPointer := FirstPointer;
WriteLn ('The contents of the list: ');
If currentpointer = Nil Then
Begin
WriteLn;
WriteLn ('The bookcase is empty');
Delay (800);
End;
While CurrentPointer <> Nil Do
Begin
With CurrentPointer^. DataField Do
Begin
WriteLn;
Write ('Bookname : '); WriteLn (bookname);
Write ('Author : '); WriteLn (author);
Write ('Publisher : '); WriteLn (publisher);
Write ('Publication year : '); WriteLn (Year);
Write ('Size : '); WriteLn (Size);
Write ('Pages : '); WriteLn (pages);
Write ('Sale price : '); WriteLn ('$', price : 4 : 2);
Write ('Brief introduction : '); WriteLn (intro);
Write ('Purchase (y/n)? : '); ReadLn (purchase);
Repeat
purchase := UpCase (purchase);
If Not (purchase In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Purchase (y/n)? : '); ReadLn (purchase);
End;
Until (purchase = 'N') Or (purchase = 'Y');
If purchase = 'Y' Then
Delrecord (currentpointer) {This currentpointer record will be}
Else {pass to the delrecord procedure }
CurrentPointer := CurrentPointer^. NextField;
End;
Write ('View the next (y/n)? : '); ReadLn (viewnext);
Repeat
viewnext := UpCase (viewnext);
If Not (viewnext In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('View the next (y/n)? : '); ReadLn (viewnext);
End;
Until (viewnext = 'N') Or (viewnext = 'Y');
If viewnext = 'Y' Then
Begin
If currentpointer = Nil Then
currentpointer := firstpointer;
Continue;
End
Else
If viewnext = 'N' Then
CurrentPointer := FirstPointer;
Exit;
End;
End;
{*************************
Procedure Name : Sold
Input : Invoke by main menu of the program.
Task : It keep track of all the book purchased during the view book
procedure where user have the option to purchase the book.
Output: Display all the book purchased by the user.
**************************
Procedure Sold;
Begin
End;
{*************************
Procedure Name : Search
Input : Invoke by main menu of the program.
Task : Using year field in the record, the program will search through
all the records and display results that match the query.
Output: Display all the book based on the year input by the user.
**************************
Procedure Search;
Var
found : Boolean;
bk_year : Integer;
PreviousPointer: ListPointer;
CurrentPointer : ListPointer;
Again : Char;
Input : Char;
Begin
Repeat
Repeat
Found := False;
Write ('Please input the year of the book (1900-2000) > '); ReadLn (bk_year);
Begin
PreviousPointer := Nil;
CurrentPointer := FirstPointer;
While (CurrentPointer <> Nil) And (Not Found) Do
If CurrentPointer^. DataField. Year = bk_year Then
Found := True
Else
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField
End
End;
If Not Found Then
Begin
WriteLn ('Sorry no book published in ', bk_year, ' is for sale');
Repeat
Write ('Press "y" to try again : '); ReadLn (again);
If Not (again In ['Y', 'y'] ) Then
Begin
WriteLn ('Press "y" to try again : ');
End;
Until (again In ['y', 'Y'] );
End
Else
With CurrentPointer^. DataField Do
Begin
WriteLn;
Write ('Bookname : '); WriteLn (bookname);
Write ('Author : '); WriteLn (author);
Write ('Publisher : '); WriteLn (publisher);
Write ('Publication year : '); WriteLn (Year);
Write ('Size : '); WriteLn (Size);
Write ('Pages : '); WriteLn (pages);
Write ('Sale price : '); WriteLn ('$', price : 4 : 2);
Write ('Brief introduction : '); WriteLn (intro);
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
End;
Until found = True;
Until (Input = 'M');
End;
{*************************
Procedure Name : Main_Menu
Input : Invoke by main body of the program.
Task : It display to use the choices he can do, input books records,
reset book records or view and purchase the books.
Output: Display the main menu of the program and awaits user inputs.
**************************
Procedure Main_Menu;
Var
Option : Char ;
Begin
Repeat
ClrScr;
WriteLn ('Books for Sale');
WriteLn ('--------------');
WriteLn ('1. View books');
WriteLn ('2. Initialise bookcase');
WriteLn ('3. Add Books');
WriteLn ('4. Display the books sold');
WriteLn ('5. Search a book');
WriteLn ('0. Quit');
Write ('Enter your choice > '); ReadLn (Option);
Case Option Of
'1': Readlist;
'2': Initialise;
'3': Addbook;
'4': Sold;
'5': Search;
'0': Exit
Else
Write ('Invalid Choice, Please enter 1, 2, 3 or 0');
Delay (300);
ClrScr;
End;
Until Option = '0';
End;
{*************************
{Main Body of the Program}
{*************************
Begin
ClrScr; {Ensure the program start in a fresh new screen}
Main_menu
End.
And the question is?
Program Books;
Uses
Crt; {Use because of clear screen command used}
Type
DataRecord = Record
Bookname : String [50];
Author : String [30];
Publisher : String [30];
Year : Integer ;
Size : String [ 2];
Pages : Integer ;
Price : Real ;
Intro : String [30];
End; {end of record}
ListPointer = ^ListRecord;
ListRecord = Record
DataField : DataRecord; {data field type}
PrevField : ListPointer; {Just Add a double link <- Data ->}
NextField : ListPointer {pointer address to next book}
End;
Var
FirstPointer : ListPointer;
LastPointer : ListPointer;
{ Procedure to sort the list using the bubble sort method }
Procedure Sort_List;
Var
Index1,Index2: Integer;
MaxNum: Integer;
Previous: ListPointer;
Current: ListPointer;
{ Function to count the number of items in the list.}
Function Count_Items: Integer;
Var
I: Integer;
CurrentPointer : ListPointer;
Begin
CurrentPointer:=FirstPoint er;
I:=0;
While CurrentPointer <> Nil Do
Begin
I:=I+1;
CurrentPointer:=CurrentPoi nter^.Next Field;
End;
Count_Items:=I;
End;
Procedure ChangePlaces(Var Prev,Curr: ListPointer);
Var
Temp: DataRecord;
Begin
Temp:=Prev^.DataField;
Prev^.DataField:=Curr^.Dat aField;
Curr^.DataField:=Temp;
End;
Begin
MaxNum:=Count_Items;
If MaxNum > 1 then
Begin
Previous:=FirstPointer;
Current:=LastPointer;
For Index1:=1 To MaxNum-1 Do
Begin
For Index2:=MaxNum DownTo Index1+1 Do
Begin
If Previous^.DataField.Year > Current^.DataField.Year Then
ChangePlaces(Previous,Curr ent);
Current:=Current^.PrevFiel d
End;
Previous:=Previous^.NextFi eld;
Current:=LastPointer
End
End
End;
Procedure ViewAll;
Var
Current: ListPointer;
Begin
Current:=FirstPointer;
While Current <> NIL Do
Begin
With Current^.DataField Do
Begin
Write(Year,' ');
Write(Bookname,' ');
Write(Author,' ');
Write(Publisher,' ');
Write(Size,' ');
Write(Pages,' ');
Write(Price,' ');
WriteLn(Intro,' ');
End;
Current:=Current^.NextFiel d
End;
WriteLn(#10#13'Press Enter to go to Menu'); ReadLn
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Initialise
Input : Invoke by main program to do initialise all the pointers.
Task : Initialise and set the relationship for current, firstpointer
,nextfield and clear data that may exist in currentpointer
Output: It will reset and clear all data present in the records/pointers.
************************** ********** ********** ********** ********** ******* }
Procedure Initialise;
Var
Input : Char;
CurrentPointer : ListPointer;
Begin
While Assigned (FirstPointer) Do {Test if a pointer variable is nil}
Begin
CurrentPointer := FirstPointer; {Force current pointer to first node}
FirstPointer := FirstPointer^. NextField;
Dispose (CurrentPointer); {Once first node deleted, rest also}
End;
WriteLn ('The bookcase is Empty but ready for books.');
Repeat
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
Until Input = 'M'
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Addbook
Input : Invoke by main program to do capturing of all books.
Task : Accept user input on the books and save it to the record.
Output: Record will hold all the data and store into memory
************************** ********** ********** ********** ********** ******* }
Procedure Addbook;
Var
CurrentPointer, TempPointer : ListPointer;
Continue : Char;
Begin
Repeat
New (CurrentPointer); {Creates a new dynamic variable}
With CurrentPointer^. DataField Do
Begin
WriteLn;
WriteLn ('Please input details including');
Write ('Bookname : '); ReadLn (Bookname );
Write ('Author : '); ReadLn (Author );
Write ('Publisher : '); ReadLn (Publisher);
Write ('Publication year : '); ReadLn (Year );
Write ('Size : '); ReadLn (Size );
Write ('Pages : '); ReadLn (Pages );
Write ('Sale price : '); ReadLn (Price );
Write ('Brief introduction : '); ReadLn (Intro );
End;
CurrentPointer^. NextField := Nil; {Ensure & set next node to nil}
If FirstPointer = Nil Then {Is first node empty? }
Begin
CurrentPointer^.PrevField: =NIL;
FirstPointer := CurrentPointer {Setting the first node }
End
Else
Begin
TempPointer := FirstPointer;
While TempPointer^. NextField <> Nil Do
TempPointer := TempPointer^. NextField; {Set next node}
TempPointer^. NextField := CurrentPointer;
CurrentPointer^.PrevField: =TempPoint er;
End;
{Add this line to know where the Link Ends}
LastPointer:=CurrentPointe r;
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
While (Continue <> 'Y') And (Continue <> 'N') Do
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
Delay (300);
End;
Until Continue = 'N';
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : DelRecord
Input : Invoke by readlist procedure to delete current record.
Task : Delete current record from record and.
Output: Current book record will be remove from the main book record.
************************** ********** ********** ********** ********** ******* }
Procedure DelRecord (Var RecordToDelete : ListPointer);
Var
CurrentPointer, PreviousPointer : ListPointer;
Begin
CurrentPointer := FirstPointer;
While (CurrentPointer <> RecordToDelete) And (CurrentPointer <> Nil) Do
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField;
End;
If CurrentPointer <> Nil Then { NIL would mean "not found" }
Begin
If CurrentPointer = FirstPointer Then { Is it the first Record? }
FirstPointer := CurrentPointer^. NextField
Else
PreviousPointer^. NextField := CurrentPointer^. NextField;
End;
RecordToDelete := CurrentPointer^. NextField;
Dispose (CurrentPointer);
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Readlist
Input : Invoke by main_menu procedure to display all the records.
Task : Read and display the contents of the list.
Output: Display all the books informations in the record, one at a time.
************************** ********** ********** ********** ********** ******* }
Procedure ReadList;
Var
CurrentPointer : ListPointer;
Purchase : Char;
ViewNext : Char;
Begin
CurrentPointer := FirstPointer;
WriteLn ('The contents of the list: ');
If currentpointer = Nil Then
Begin
WriteLn;
WriteLn ('The bookcase is empty');
Delay (800);
End;
While CurrentPointer <> Nil Do
Begin
With CurrentPointer^. DataField Do
Begin
WriteLn;
WriteLn ('Bookname : ',bookname);
WriteLn ('Author : ',author);
WriteLn ('Publisher : ',publisher);
WriteLn ('Publication year : ',Year);
WriteLn ('Size : ',Size);
WriteLn ('Pages : ',pages);
WriteLn ('Sale price : ','$',price:4:2);
WriteLn ('Brief introduction : ',intro);
Write ('Purchase (y/n)? : '); ReadLn (purchase);
Repeat
purchase := UpCase (purchase);
If Not (purchase In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Purchase (y/n)? : '); ReadLn (purchase);
End;
Until (purchase = 'N') Or (purchase = 'Y');
If purchase = 'Y' Then
Delrecord (currentpointer) {This currentpointer record will be}
Else {pass to the delrecord procedure }
CurrentPointer := CurrentPointer^. NextField;
End;
Write ('View the next (y/n)? : '); ReadLn (viewnext);
Repeat
viewnext := UpCase (viewnext);
If Not (viewnext In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('View the next (y/n)? : '); ReadLn (viewnext);
End;
Until (viewnext = 'N') Or (viewnext = 'Y');
If viewnext = 'Y' Then
Begin
If currentpointer = Nil Then
currentpointer := firstpointer;
Continue;
End
Else
If viewnext = 'N' Then
CurrentPointer := FirstPointer;
Exit;
End;
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Sold
Input : Invoke by main menu of the program.
Task : It keep track of all the book purchased during the view book
procedure where user have the option to purchase the book.
Output: Display all the book purchased by the user.
************************** ********** ********** ********** ********** ******* }
Procedure Sold;
Begin
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Search
Input : Invoke by main menu of the program.
Task : Using year field in the record, the program will search through
all the records and display results that match the query.
Output: Display all the book based on the year input by the user.
************************** ********** ********** ********** ********** ******* }
Procedure Search;
Var
found : Boolean;
bk_year : Integer;
PreviousPointer: ListPointer;
CurrentPointer : ListPointer;
Again : Char;
Input : Char;
Begin
Repeat
Repeat
Found := False;
Write ('Please input the year of the book (1900-2000) > ');
ReadLn (bk_year);
PreviousPointer := Nil;
CurrentPointer := FirstPointer;
While (CurrentPointer <> Nil) And (Not Found) Do
If CurrentPointer^. DataField. Year = bk_year Then
Found := True
Else
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField
End;
If Not Found Then
Begin
WriteLn ('Sorry no book published in ', bk_year, ' is for sale');
Repeat
Write ('Press "y" to try again : '); ReadLn (again);
If Not (again In ['Y', 'y'] ) Then
WriteLn ('Press "y" to try again : ');
Until (again In ['y', 'Y'] );
End
Else
With CurrentPointer^. DataField Do
Begin
WriteLn;
Write ('Bookname : '); WriteLn (bookname);
Write ('Author : '); WriteLn (author);
Write ('Publisher : '); WriteLn (publisher);
Write ('Publication year : '); WriteLn (Year);
Write ('Size : '); WriteLn (Size);
Write ('Pages : '); WriteLn (pages);
Write ('Sale price : '); WriteLn ('$', price : 4 : 2);
Write ('Brief introduction : '); WriteLn (intro);
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
End;
Until found = True;
Until (Input = 'M');
End;
{************************* ********** ********** ********** ********** *******
Procedure Name : Main_Menu
Input : Invoke by main body of the program.
Task : It display to use the choices he can do, input books records,
reset book records or view and purchase the books.
Output: Display the main menu of the program and awaits user inputs.
************************** ********** ********** ********** ********** ******* }
Procedure Main_Menu;
Var
Option : Char ;
Begin
Repeat
ClrScr;
WriteLn ('Books for Sale');
WriteLn ('--------------');
WriteLn ('1. View books');
WriteLn ('2. Initialise bookcase');
WriteLn ('3. Add Books');
WriteLn ('4. Display the books sold');
WriteLn ('5. Search a book');
WriteLn ('6. Sort_List');
WriteLn ('7. View all Records');
WriteLn ('0. Quit');
Write ('Enter your choice > '); ReadLn (Option);
Case Option Of
'1': Readlist;
'2': Initialise;
'3': Addbook;
'4': Sold;
'5': Search;
'6': Sort_List;
'7': ViewAll;
'0': Exit
Else
Write ('Invalid Choice, Please enter 1, 2, 3 or 0');
Delay (300);
ClrScr;
End;
Until Option = '0';
End;
{************************* ********** ********** ********** ********** ****}
{Main Body of the Program}
{************************* ********** ********** ********** ********** ****}
Begin
ClrScr; {Ensure the program start in a fresh new screen}
Main_menu
End.
Uses
Crt; {Use because of clear screen command used}
Type
DataRecord = Record
Bookname : String [50];
Author : String [30];
Publisher : String [30];
Year : Integer ;
Size : String [ 2];
Pages : Integer ;
Price : Real ;
Intro : String [30];
End; {end of record}
ListPointer = ^ListRecord;
ListRecord = Record
DataField : DataRecord; {data field type}
PrevField : ListPointer; {Just Add a double link <- Data ->}
NextField : ListPointer {pointer address to next book}
End;
Var
FirstPointer : ListPointer;
LastPointer : ListPointer;
{ Procedure to sort the list using the bubble sort method }
Procedure Sort_List;
Var
Index1,Index2: Integer;
MaxNum: Integer;
Previous: ListPointer;
Current: ListPointer;
{ Function to count the number of items in the list.}
Function Count_Items: Integer;
Var
I: Integer;
CurrentPointer : ListPointer;
Begin
CurrentPointer:=FirstPoint
I:=0;
While CurrentPointer <> Nil Do
Begin
I:=I+1;
CurrentPointer:=CurrentPoi
End;
Count_Items:=I;
End;
Procedure ChangePlaces(Var Prev,Curr: ListPointer);
Var
Temp: DataRecord;
Begin
Temp:=Prev^.DataField;
Prev^.DataField:=Curr^.Dat
Curr^.DataField:=Temp;
End;
Begin
MaxNum:=Count_Items;
If MaxNum > 1 then
Begin
Previous:=FirstPointer;
Current:=LastPointer;
For Index1:=1 To MaxNum-1 Do
Begin
For Index2:=MaxNum DownTo Index1+1 Do
Begin
If Previous^.DataField.Year > Current^.DataField.Year Then
ChangePlaces(Previous,Curr
Current:=Current^.PrevFiel
End;
Previous:=Previous^.NextFi
Current:=LastPointer
End
End
End;
Procedure ViewAll;
Var
Current: ListPointer;
Begin
Current:=FirstPointer;
While Current <> NIL Do
Begin
With Current^.DataField Do
Begin
Write(Year,' ');
Write(Bookname,' ');
Write(Author,' ');
Write(Publisher,' ');
Write(Size,' ');
Write(Pages,' ');
Write(Price,' ');
WriteLn(Intro,' ');
End;
Current:=Current^.NextFiel
End;
WriteLn(#10#13'Press Enter to go to Menu'); ReadLn
End;
{*************************
Procedure Name : Initialise
Input : Invoke by main program to do initialise all the pointers.
Task : Initialise and set the relationship for current, firstpointer
,nextfield and clear data that may exist in currentpointer
Output: It will reset and clear all data present in the records/pointers.
**************************
Procedure Initialise;
Var
Input : Char;
CurrentPointer : ListPointer;
Begin
While Assigned (FirstPointer) Do {Test if a pointer variable is nil}
Begin
CurrentPointer := FirstPointer; {Force current pointer to first node}
FirstPointer := FirstPointer^. NextField;
Dispose (CurrentPointer); {Once first node deleted, rest also}
End;
WriteLn ('The bookcase is Empty but ready for books.');
Repeat
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
Until Input = 'M'
End;
{*************************
Procedure Name : Addbook
Input : Invoke by main program to do capturing of all books.
Task : Accept user input on the books and save it to the record.
Output: Record will hold all the data and store into memory
**************************
Procedure Addbook;
Var
CurrentPointer, TempPointer : ListPointer;
Continue : Char;
Begin
Repeat
New (CurrentPointer); {Creates a new dynamic variable}
With CurrentPointer^. DataField Do
Begin
WriteLn;
WriteLn ('Please input details including');
Write ('Bookname : '); ReadLn (Bookname );
Write ('Author : '); ReadLn (Author );
Write ('Publisher : '); ReadLn (Publisher);
Write ('Publication year : '); ReadLn (Year );
Write ('Size : '); ReadLn (Size );
Write ('Pages : '); ReadLn (Pages );
Write ('Sale price : '); ReadLn (Price );
Write ('Brief introduction : '); ReadLn (Intro );
End;
CurrentPointer^. NextField := Nil; {Ensure & set next node to nil}
If FirstPointer = Nil Then {Is first node empty? }
Begin
CurrentPointer^.PrevField:
FirstPointer := CurrentPointer {Setting the first node }
End
Else
Begin
TempPointer := FirstPointer;
While TempPointer^. NextField <> Nil Do
TempPointer := TempPointer^. NextField; {Set next node}
TempPointer^. NextField := CurrentPointer;
CurrentPointer^.PrevField:
End;
{Add this line to know where the Link Ends}
LastPointer:=CurrentPointe
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
While (Continue <> 'Y') And (Continue <> 'N') Do
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Add more (y/n) ? : '); ReadLn (Continue);
Continue := UpCase (Continue);
Delay (300);
End;
Until Continue = 'N';
End;
{*************************
Procedure Name : DelRecord
Input : Invoke by readlist procedure to delete current record.
Task : Delete current record from record and.
Output: Current book record will be remove from the main book record.
**************************
Procedure DelRecord (Var RecordToDelete : ListPointer);
Var
CurrentPointer, PreviousPointer : ListPointer;
Begin
CurrentPointer := FirstPointer;
While (CurrentPointer <> RecordToDelete) And (CurrentPointer <> Nil) Do
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField;
End;
If CurrentPointer <> Nil Then { NIL would mean "not found" }
Begin
If CurrentPointer = FirstPointer Then { Is it the first Record? }
FirstPointer := CurrentPointer^. NextField
Else
PreviousPointer^. NextField := CurrentPointer^. NextField;
End;
RecordToDelete := CurrentPointer^. NextField;
Dispose (CurrentPointer);
End;
{*************************
Procedure Name : Readlist
Input : Invoke by main_menu procedure to display all the records.
Task : Read and display the contents of the list.
Output: Display all the books informations in the record, one at a time.
**************************
Procedure ReadList;
Var
CurrentPointer : ListPointer;
Purchase : Char;
ViewNext : Char;
Begin
CurrentPointer := FirstPointer;
WriteLn ('The contents of the list: ');
If currentpointer = Nil Then
Begin
WriteLn;
WriteLn ('The bookcase is empty');
Delay (800);
End;
While CurrentPointer <> Nil Do
Begin
With CurrentPointer^. DataField Do
Begin
WriteLn;
WriteLn ('Bookname : ',bookname);
WriteLn ('Author : ',author);
WriteLn ('Publisher : ',publisher);
WriteLn ('Publication year : ',Year);
WriteLn ('Size : ',Size);
WriteLn ('Pages : ',pages);
WriteLn ('Sale price : ','$',price:4:2);
WriteLn ('Brief introduction : ',intro);
Write ('Purchase (y/n)? : '); ReadLn (purchase);
Repeat
purchase := UpCase (purchase);
If Not (purchase In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('Purchase (y/n)? : '); ReadLn (purchase);
End;
Until (purchase = 'N') Or (purchase = 'Y');
If purchase = 'Y' Then
Delrecord (currentpointer) {This currentpointer record will be}
Else {pass to the delrecord procedure }
CurrentPointer := CurrentPointer^. NextField;
End;
Write ('View the next (y/n)? : '); ReadLn (viewnext);
Repeat
viewnext := UpCase (viewnext);
If Not (viewnext In ['Y', 'N'] ) Then
Begin
WriteLn ('Invalid! Accept Y/N only');
Write ('View the next (y/n)? : '); ReadLn (viewnext);
End;
Until (viewnext = 'N') Or (viewnext = 'Y');
If viewnext = 'Y' Then
Begin
If currentpointer = Nil Then
currentpointer := firstpointer;
Continue;
End
Else
If viewnext = 'N' Then
CurrentPointer := FirstPointer;
Exit;
End;
End;
{*************************
Procedure Name : Sold
Input : Invoke by main menu of the program.
Task : It keep track of all the book purchased during the view book
procedure where user have the option to purchase the book.
Output: Display all the book purchased by the user.
**************************
Procedure Sold;
Begin
End;
{*************************
Procedure Name : Search
Input : Invoke by main menu of the program.
Task : Using year field in the record, the program will search through
all the records and display results that match the query.
Output: Display all the book based on the year input by the user.
**************************
Procedure Search;
Var
found : Boolean;
bk_year : Integer;
PreviousPointer: ListPointer;
CurrentPointer : ListPointer;
Again : Char;
Input : Char;
Begin
Repeat
Repeat
Found := False;
Write ('Please input the year of the book (1900-2000) > ');
ReadLn (bk_year);
PreviousPointer := Nil;
CurrentPointer := FirstPointer;
While (CurrentPointer <> Nil) And (Not Found) Do
If CurrentPointer^. DataField. Year = bk_year Then
Found := True
Else
Begin
PreviousPointer := CurrentPointer;
CurrentPointer := CurrentPointer^. NextField
End;
If Not Found Then
Begin
WriteLn ('Sorry no book published in ', bk_year, ' is for sale');
Repeat
Write ('Press "y" to try again : '); ReadLn (again);
If Not (again In ['Y', 'y'] ) Then
WriteLn ('Press "y" to try again : ');
Until (again In ['y', 'Y'] );
End
Else
With CurrentPointer^. DataField Do
Begin
WriteLn;
Write ('Bookname : '); WriteLn (bookname);
Write ('Author : '); WriteLn (author);
Write ('Publisher : '); WriteLn (publisher);
Write ('Publication year : '); WriteLn (Year);
Write ('Size : '); WriteLn (Size);
Write ('Pages : '); WriteLn (pages);
Write ('Sale price : '); WriteLn ('$', price : 4 : 2);
Write ('Brief introduction : '); WriteLn (intro);
Write ('Press "m" to return to Main Menu > ');
ReadLn (Input);
Input := UpCase (Input); {allow m or M to be accepted}
End;
Until found = True;
Until (Input = 'M');
End;
{*************************
Procedure Name : Main_Menu
Input : Invoke by main body of the program.
Task : It display to use the choices he can do, input books records,
reset book records or view and purchase the books.
Output: Display the main menu of the program and awaits user inputs.
**************************
Procedure Main_Menu;
Var
Option : Char ;
Begin
Repeat
ClrScr;
WriteLn ('Books for Sale');
WriteLn ('--------------');
WriteLn ('1. View books');
WriteLn ('2. Initialise bookcase');
WriteLn ('3. Add Books');
WriteLn ('4. Display the books sold');
WriteLn ('5. Search a book');
WriteLn ('6. Sort_List');
WriteLn ('7. View all Records');
WriteLn ('0. Quit');
Write ('Enter your choice > '); ReadLn (Option);
Case Option Of
'1': Readlist;
'2': Initialise;
'3': Addbook;
'4': Sold;
'5': Search;
'6': Sort_List;
'7': ViewAll;
'0': Exit
Else
Write ('Invalid Choice, Please enter 1, 2, 3 or 0');
Delay (300);
ClrScr;
End;
Until Option = '0';
End;
{*************************
{Main Body of the Program}
{*************************
Begin
ClrScr; {Ensure the program start in a fresh new screen}
Main_menu
End.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.