W oparciu o powyższe dwa programy (zdjęcia w załącznikach) napisz program w PASCALU (FREE PASCALU) w którym jednocześnie będzie można zapisywać i odczytywać, dopisywać i usuwać dane z plików.
W oparciu o typ rekordowy danych napisz program gromadzacy informacje na temat:
liczba oktanowa, cena, stacja benzynowa.
" Life is not a problem to be solved but a reality to be experienced! "
© Copyright 2013 - 2024 KUDO.TIPS - All rights reserved.
Niezbyt jasno opisany problem :/
Program pisany pod FPC 2.6.0 na Win32; pod innymi wersjami kompilatora oraz innymi architekturami nie testowany!
BTW: te kartki były pisane chyba pod TP 7 (a nawet chyba nie, ponieważ są one bezsensowne i błędne), gdzie był limit na 255 znaków w stringu. Aktualnie FPC domyślnie ma włączone ansistringi bez tego limitu, to tak swoją drogą.
Oparte na linked list ;)
LINK DO KODU: http://pastebin.com/0WwtN39h
Kod (uwaga, grubo ponad 400 linijek!):
{$MODE OBJFPC}{$H+}
Program zadane;
Uses SysUtils, CRT;
Const C_FILENAME = 'file.data';
Magic = 123;
Type TElement = Record
LiczbaOktanowa : Integer;
Cena : Integer;
StacjaBenzynowa: Byte; { ??? }
End;
Type generic TList<T> = Class
Type PNode = ^TNode;
TNode = Record
Value: T;
Next : PNode;
End;
Private
Temp: PNode;
Public
Head, Tail, Tmp: PNode;
Constructor Create;
Procedure Free;
Procedure Add(Value: T);
Function Insert(Index: Integer; Value: T): Integer;
Procedure Delete(Index: Integer);
Function Get(Index: Integer): TNode;
Procedure Replace(Index: Integer; NewValue: T);
Function Count: Integer;
Property Element[Index: Integer]: TNode read Get; default;
End;
Type TMyList = specialize TList<TElement>;
Type TFile = Class
Private
List: TMyList;
Public
Property fList: TMyList read List;
Constructor Create;
Function Open: Boolean;
Function Save: Boolean;
End;
{ ===== TList ===== }
{ TList.Create }
Constructor TList.Create;
Begin
Head := nil;
Tail := Head;
End;
{ TList.Free }
Procedure TList.Free;
Begin
Temp := Head;
While (Temp <> nil) Do
Begin
Temp := Temp^.Next;
Dispose(Head);
Head := Temp;
End;
End;
{ TList.Add }
Procedure TList.Add(Value: T);
Begin
New(Temp);
Temp^.Value := Value;
Temp^.Next := nil;
if (Head = nil) Then
Head := Temp Else
Tail^.Next := Temp;
Tail := Temp;
End;
{ TList.Insert }
Function TList.Insert(Index: Integer; Value: T): Integer;
Var I : Integer;
Node, TempNode: TNode;
Done : Boolean=False;
Begin
Result := Index;
I := 0;
Temp := Head;
Node.Value := Value;
New(Node.Next);
if (Index = 0) Then
Begin
TempNode := Head^;
Head^ := Node;
Node.Next^ := TempNode;
Done := True;
End;
if (not Done) Then
While (I < Index-1) Do
Begin
if (Temp^.Next^.Next = nil) Then
Begin
Done := True;
Break;
End;
Inc(I);
Temp := Temp^.Next;
End;
if (not Done) Then
Begin
TempNode := Temp^.Next^;
Temp^.Next^ := Node;
Node.Next^ := TempNode;
End;
End;
{ TList.Delete }
Procedure TList.Delete(Index: Integer);
Var Prev: PNode;
D : Integer=0;
Done: Boolean=False;
Begin
if (Head = nil) Then
Exit;
Prev := Head;
Temp := Head;
While (true) do
Begin
if (D = Index) Then
Break;
if (Temp^.Next^.Next = nil) Then
Begin
Done := True;
Break;
End;
Prev := Temp;
Temp := Temp^.Next;
Inc(D);
End;
if (not Done) Then
if (Temp = Head) Then
Begin
Dispose(Head);
Head := Head^.Next;
End Else
Begin
Dispose(Prev^.Next);
Prev^.Next := Temp^.Next;
End;
End;
{ TList.Get }
Function TList.Get(Index: Integer): TNode;
Var I: Integer;
Begin
Temp := Head;
For I := 0 To Index-1 Do
Temp := Temp^.Next;
Result := Temp^;
End;
{ TList.Replace }
Procedure TList.Replace(Index: Integer; NewValue: T);
Var I: Integer;
Begin
Temp := Head;
For I := 0 To Index-1 Do
Temp := Temp^.Next;
Temp^.Value := NewValue;
End;
{ TList.Count }
Function TList.Count: Integer;
Begin
Result := 0;
Temp := Head;
While (Temp <> nil) Do
Begin
Temp := Temp^.Next;
Inc(Result);
End;
End;
{ ===== TFile ===== }
{ TFile.Create }
Constructor TFile.Create;
Begin
List := TMyList.Create;
End;
{ TFile.Open }
Function TFile.Open: Boolean;
Var F : File;
Count: Byte=0;
I : Byte;
Rec : TElement;
Begin
if (Assigned(List)) Then
List.Free;
Result := True;
Try
if (not FileExists(C_FILENAME)) Then
raise Exception.Create('File not found');
Try
AssignFile(F, C_FILENAME);
Reset(F, 1);
if (FileSize(F) < sizeof(TElement)+3) Then
raise Exception.Create('Wrong file size');
BlockRead(F, Count, sizeof(Count));
List := TMyList.Create;
For I := 1 To Count Do
Begin
BlockRead(F, Rec.LiczbaOktanowa, sizeof(Rec.LiczbaOktanowa));
BlockRead(F, Rec.Cena, sizeof(Rec.Cena));
BlockRead(F, Rec.StacjaBenzynowa, sizeof(Rec.StacjaBenzynowa));
List.Add(Rec);
End;
BlockRead(F, I, sizeof(I));
if (I <> Magic) Then
raise Exception.Create('Wrong magic');
if (not EOF(F)) Then
raise Exception.Create('not EOF');
Finally
CloseFile(F);
End;
Except
Result := False;
raise;
End;
End;
{ TFile.Save }
Function TFile.Save: Boolean;
Var F: File;
I: Byte;
E: TElement;
Begin
Result := True;
Try
Try
if (List = nil) Then
raise Exception.Create('TFile.Save :: List = nil');
AssignFile(F, C_FILENAME);
ReWrite(F, 1);
I := List.Count;
BlockWrite(F, I, sizeof(I));
Writeln(I);
For I := 0 To I-1 Do
Begin
E := List[I].Value;
BlockWrite(F, E.LiczbaOktanowa, sizeof(E.LiczbaOktanowa));
BlockWrite(F, E.Cena, sizeof(E.Cena));
BlockWrite(F, E.StacjaBenzynowa, sizeof(E.StacjaBenzynowa));
End;
I := Magic;
BlockWrite(F, I, sizeof(I));
Finally
CloseFile(F);
End;
Except
raise;
End;
End;
Var GFile: TFile;
{ Menu }
Procedure Menu;
{ f_OPEN }
Procedure f_OPEN;
Begin
GFile.Open;
End;
{ f_SAVE }
Procedure f_SAVE;
Begin
GFile.Save;
End;
{ f_NEW }
Procedure f_NEW;
Var Rec: TElement;
Begin
Write('Liczba oktanowa: ');
Readln(Rec.LiczbaOktanowa);
Write('Cena: ');
Readln(Rec.Cena);
Write('Stacja benzynowa: ');
Readln(Rec.StacjaBenzynowa);
GFile.List.Add(Rec);
Writeln('Dodano - ID = ', GFile.List.Count-1);
Readln;
End;
{ f_REMOVE }
Procedure f_REMOVE;
Var ID: Integer;
Begin
Write('ID: ');
Readln(ID);
if (ID < 0) or (ID >= GFile.List.Count) Then
raise Exception.Create('Invalid ID!');
GFile.List.Delete(ID);
End;
{ f_EDIT }
Procedure f_EDIT;
Var ID : Integer;
Rec: TElement;
Begin
Write('ID: ');
Readln(ID);
if (ID < 0) or (ID >= GFile.List.Count) Then
raise Exception.Create('Invalid ID!');
Rec := GFile.List[ID].Value;
Writeln('Liczba oktanowa = ', Rec.LiczbaOktanowa);
Writeln('Cena = ', Rec.Cena);
Writeln('Stacja benzynowa = ', Rec.StacjaBenzynowa);
Writeln;
Writeln('-- nowe --');
Writeln;
Write('Liczba oktanowa: ');
Readln(Rec.LiczbaOktanowa);
Write('Cena: ');
Readln(Rec.Cena);
Write('Stacja benzynowa: ');
Readln(Rec.StacjaBenzynowa);
GFile.List.Replace(ID, Rec);
End;
{ f_VIEW }
Procedure f_VIEW;
Var Count: Integer;
Rec : TElement;
Begin
Count := GFile.List.Count;
Writeln('Lacznie elementow: ', Count);
Writeln;
For Count := 0 To Pred(Count) Do
Begin
Rec := GFile.List[Count].Value;
Writeln('#', Count);
Writeln('Liczba oktanowa = ', Rec.LiczbaOktanowa);
Writeln('Cena = ', Rec.Cena);
Writeln('Stacja benzynowa = ', Rec.StacjaBenzynowa);
Writeln;
End;
Readln;
End;
Var Str: String;
Begin
ClrScr;
Writeln('-- menu glowne --');
Writeln('open - wczytuje plik');
Writeln('save - zapisuje plik');
Writeln('new - pozwala dodac nowy rekord');
Writeln('remove - usuwa rekord');
Writeln('edit - pozwala edytowac rekord');
Writeln('view - wyswietla wszystkie rekordy');
Writeln('exit - wychodzi z programu');
Write('$ ');
Readln(Str);
ClrScr;
Str := Trim(LowerCase(Str));
Case Str of
'open' : f_OPEN;
'save' : f_SAVE;
'new' : f_NEW;
'remove': f_REMOVE;
'edit' : f_EDIT;
'view' : f_VIEW;
'exit' : Halt;
End;
Menu;
End;
Begin
GFile := TFile.Create;
Try
Menu;
Except
On E: Exception Do
Begin
Writeln('Exception!');
Writeln(E.Message);
Readln;
End;
End;
GFile.Free;
End.