visitor (0 QPoints)
  • FR
  • EN
  • NL
  • DE
  • ES
315 experts, 1193 registered users, 1659 questions already answered
European Experts Exchange, the very best site for high-quality IT solutions

New Improved Search!

 


05/10/2011 1h30 : Steve Jobs is dead, the father of Apple ][ is gone, we are all orphaned.

Languages :: Pascal :: Reading and Writing Linked ListsTo Files


By: VB guy Canada  Date: 13/06/2003 00:00:00  English  Points: 50 Status: Answered
Quality : Excellent
I have these to procedures to read and write a linked list to the file. here is how the linked list is decleared.

TYPE
InventoryPTR = ^DBPTR;
DBPTR = Record
Code : INTEGER;
NumStock : INTEGER;
Max : INTEGER;
Min : INTEGER;
Price : REAL;
Item : STRING[20];
NextPTR : InventoryPTR;
end;

VAR head, Current, DB : InventoryPTR;
InventoryFile : file of InventoryPTR;

and this is the reading from the file :

Procedure FileRead(var DataBase : InventoryPTR);
var i : integer;
Begin
{$I-}
RESET(InventoryFile);
{$I+}
IF IORESULT <> 0 Then
Begin
{$I-}
REWRITE(InventoryFile);
{$I+}
End;
i := 0;
Repeat
IF eof(InventoryFile) = FALSE Then
Begin
IF Head = nil THEN
BEGIN
new(DataBase);
read(InventoryFile, Database);
seek(InventoryFile,i);
Head := DataBase;
Current := DataBase;
DataBase^.NextPTR := nil;
END {IF}
Else
BEGIN
new(Database);
Current^.NextPTR := DataBase;
read(InventoryFile, Database);
seek(InventoryFile,i);
Current := DataBase;
DataBase^.NextPTR := nil;
End; {ELSE}
end; {IF}
i := i + 1;
until eof(InventoryFile) = true;
CLOSE(InventoryFile);
END;

and this the writing to the file

Procedure FileWrite(var DataBase : InventoryPTR);
Begin
Rewrite(InventoryFile);
Database := Head;
while database <> nil do
begin
write(InventoryFile,DataBase);
DataBase := DataBase^.NextPTR;
end; {while}
write(InventoryFile,Current);
Close(InventoryFile);
End;

Thanks to anyone who can help me fix this

:)
By: VGR Date: 13/06/2003 16:00:00 English  Type : Comment
first : shouldn't you have

InventoryFile : file of DBPTR;

?

(the records in stead of the pointers ;-)

Please note you didn't tell what was the problem 8-)))

Personally, I would write this differently using just the DBPTR (with meaningless pointer values) and when reading re-assigning sequentially the list's pointers. The number of elements is implicit, as it should be. Should be simplier
By: VGR Date: 13/06/2003 16:27:00 English  Type : Answer
fixed. See comments, I think you've some more work to do ;-)

program linklist_file2dpr;

{$APPTYPE CONSOLE}

TYPE
InventoryPTR = ^DBPTR;
DBPTR = Record
Code : INTEGER;
NumStock : INTEGER;
Max : INTEGER;
Min : INTEGER;
Price : REAL;
Item : STRING[20];
NextPTR : InventoryPTR;
end;

VAR Current, DB : InventoryPTR; (* head=database, so it's useless *)
InventoryFile : file of DBPTR;


Procedure FileRead(var DataBase : InventoryPTR);
var current : InventoryPTR;
Begin
{$I-}
RESET(InventoryFile);
{$I+}
IF IORESULT <> 0 Then
Begin
{$I-}
REWRITE(InventoryFile);
{$I+}
End;
If NOT Eof(InventoryFile) Then
Begin
IF Database = nil Then new(DataBase); (* creation database=root *)
current:=Database;
While NOT Eof(InventoryFile) Do
Begin
read(InventoryFile, current^);
current^.NextPTR := nil;
End; (* While *)
End; (* If elements found *)
(* thus database gets out untouched in case fiel is empty ; beware of reading on an existing list! There is no prior deallocation ! *)
CLOSE(InventoryFile);
END;


Procedure FileWrite(DataBase : InventoryPTR); (* var was pointless, onthe contrary (saves a pointer) *)
Begin
Rewrite(InventoryFile);
while DataBase <> nil do
begin
write(InventoryFile,DataBase^);
DataBase := DataBase^.NextPTR;
end; (* while *)
Close(InventoryFile);
End;

Begin
(* to create a sample
New(DB);
With DB^ Do Begin
Code:=1; { root }
NumStock :=0;
Max:=2;;
Min:=1;
Price:=0.01;
Item:='root';
NextPTR:=Nil;
End; { with root }
{ add & link }
New(current); DB^.NextPTR:=current;
With current^ Do Begin
Code:=2;
NumStock :=0;
Max:=2;;
Min:=1;
Price:=0.02;
Item:='second';
NextPTR:=Nil;
End; { with second element }
{ assign & write (assign has currently to be external to the procedure filewrite, while close is in... }
{ I advise you to pass an extra parameter 'filename' and perform atomic operations }
Assign(InventoryFile,'test.dat');
FileWrite(DB);
*)

(* to read an existing *)
{ assign & read (assign has currently to be external to the procedure fileread, while close is in... }
{ I advise you to pass an extra parameter 'filename' and perform atomic operations }
{ You could also - to save time - register a "number of elements found" from within FileRead (the previous 'I' variable, becoming a Var parameter) }
Assign(InventoryFile,'test.dat');
FileRead(DB);
(**)
End.

Do register to be able to answer

EContact
browser fav
page generated in 12285.017010 milliseconds

Why Google AdSense ads ?

compteur
 Ranking-Hits PageRank for this page