|
![]() |
|
Registriert seit: 7. Aug 2008 Ort: Brandenburg 1.487 Beiträge Delphi 12 Athens |
#1
Eine seperate Klasse TStorage zum Speichern läuft letztendlich auf ein Visitor-Pattern hinaus.
Damit scheint aber der TE noch leicht überfordert zu sein. Deshalb erst mal ein einfacher Lösungsansatz, der zwar nicht so universell aber dafür einfacher zu verstehen ist. Wie speichert man eine Liste von Elementen in einer Datei? Es gibt verschiedene Dateiformate die sich je nach Anwendungsfall unterschiedlich gut eignen. Eine einfache Variante ist die CSV-Datei, dabei wird für jedes Element eine Zeile gespeichert. Jede Zeile wird mit Zeilenabschluss beendet (z.B. CRLF). Innerhalb der Zeile sind die einzelnen Eigenschaften z.B. durch Komma getrennt.
Delphi-Quellcode:
Ich habe hier bewusst auf den Einsatz einer TStringList verzichtet. Wenn der TE diese Klasse und deren Möglichkeiten nicht kennt, sollte er das Probleme zuerst mit den bekannten Mitteln lösen.
TVokabel = class
{...} public function ObjectToCSV: string; procedure ObjectFromCSV(const AValue: string); end; TListe = class {...} public procedure Clear; procedure SaveToStream(AStream: TStream); procedure ReadFromStream(AStream: TStream); end; function GetNextString(var AValue: string; const ASeperator): string; var i, n: Integer; begin n := Length(ASeperator); i := Pos(ASeperator, AValue); if i > 0 then begin Result := Copy(AValue, 1, i - 1); AValue := Copy(AValue, i + n, Length(AValue) - i - n + 1); end else begin Result := AValue; AValue := ''; end; end; function TVokabel.ObjectToCSV: string; begin Result := Deutsch + ',' + Englisch; end; procedure TVokabel.ObjectFromCSV(const AValue: string); var s: string; begin s := AValue; Deutsch := GetNextString(s, ','); Englisch := GetNextString(s, ','); end; procedure TListe.SaveToStream(AStream: TStream); var vokabel: TVokabel; s: string; begin vokabel := Erste; if Assigned(vokabel) then begin repeat s := vokabel.ObjectToCSV + #13#10; AStream.WriteBuffer(PChar(s)^, Length(s)); vokabel := vokabel.naechste; until (vokabel = Erste); end; end; procedure TListe.ReadFromStream(AStream: TStream); var sBuffer, s: string; vokabel: TVokabel; begin Clear; SetLength(sBuffer, AStream.Length); AStream.ReadBuffer(PChar(sBuffer)^, Length(sBuffer)); while Length(sBuffer) > 0 do begin s := GetNextString(sBuffer, #13#10); if Length(s) > 0 then begin vokabel := TVokabel.Create; vokabel.ObjectFromCSV(s); hinzufuegen(vokabel); end; end; end; stream := TFileSream.Create('MyFile.csv', fmCreate); MyListe.SaveToStream(stream); stream.Free; stream := TFileSream.Create('MyFile.csv', fmRead); MyListe.ReadFromStream(stream); stream.Free; |
![]() |
Popov
(Gast)
n/a Beiträge |
#2
Die Ansätze von SirRufo und Blup finde ich zwar persönlich sehr gut und gelungen, und es ist erfreulich, dass der TE die Aufgabe mit einer Klasse löst (auch wenn es noch Probleme gibt, die Richtung stimmt zumindest), aber ich glaube zu erkennen (ich kann mich aber auch irren), dass sich der TE etwas verloren hat. Vor allem als Anfänger kann es problematisch sein am Anfang gleich zwei Hürden zu meistern. Die eine Hürde ist die Klasse. Ich finde man sollte sich erst einer Aufgabe widmen, bis die sitzt. Andere Probleme lenken davon ab, wie z. B. die Hürde beliebige Daten zu speichern. Deshalb meine Idee mit TStringList. Das kennt fast jeder, denn das ist einer der ersten Klassen die man sich genauer anguckt.
@thejacensolo Ich hab gerade ein Beispiel geprogt. Betrachte das nicht als fertige Klasse, auch wenn sie funktioniert. Auf Sicherheitsabfrage, Fehlermeldungen usw. habe ich verzichtet, denn es ist deine Klasse. Ich hab nur ein Beispiel gemacht in dem ich verführe wie einfach diese Aufgabe mit TStringList gelöst werden kann. Den Rest mußt du alleine machten.
Delphi-Quellcode:
Kurz zu der Beschreibung: über Create wird ein Pfad angegeben und somit eine Textdatei mit Vokalen geladen. Beim Freigeben wird automatisch gespeichert. Man kann aber auch mit AllesSpeichern selbst speichern. Über VokabelNeu wird eine Vokabel angelegt. Über Parameter gibt man das deutsche und englische Wort. Über GibVokabelEng und GibVokabelDe kann man eine Vokabel abfragen. Mit GibErsteVokabelDe, GibNaechsteVokabelDe, usw. kann man sich rauf und runter deutsche Vokabeln geben lassen. Die Englische mit der Methode oben abgefragt.
unit uListe;
interface uses SysUtils, Classes; type TVokabel2 = class private FFileName: string; FZeiger: Integer; FVokabelListe: TStringList; function GibZeigerVokabelDe(Zeiger: Integer): string; public constructor Create(const FileName: string); destructor Destroy; override; procedure VokabelNeu(Deutsch, Englisch: string); procedure VokabelBearbeiten(Deutsch, Englisch: string); function GibVokabelEng(VokabelDe: string): string; function GibVokabelDe(VokabelEng: string): string; function VokabelAnzahl: Integer; property VokabelZeiger: Integer read FZeiger; procedure AllesSpeichern; function GibErsteVokabelDe: string; function GibNaechsteVokabelDe: string; function GibVorherigeVokabelDe: string; function GibLetzteVokabelDe: string; function GibVokabelDeIndex(VokabelDe: string): Integer; procedure LoescheVokabel(Index: Integer); end; implementation constructor TVokabel2.Create(const FileName: string); begin inherited Create; FFileName := FileName; FZeiger := 0; FVokabelListe := TStringList.Create; if FileExists(FFileName) then FVokabelListe.LoadFromFile(FFileName); end; destructor TVokabel2.Destroy; begin AllesSpeichern; FVokabelListe.Free; inherited Destroy; end; procedure TVokabel2.VokabelNeu(Deutsch, Englisch: string); begin FVokabelListe.Values[Deutsch] := Englisch; end; procedure TVokabel2.VokabelBearbeiten(Deutsch, Englisch: string); begin VokabelNeu(Deutsch, Englisch); end; function TVokabel2.GibVokabelEng(VokabelDe: string): string; begin Result := FVokabelListe.Values[VokabelDe]; end; function TVokabel2.GibVokabelDe(VokabelEng: string): string; var i: Integer; begin Result := ''; for i := 0 to FVokabelListe.Count - 1 do if SameText(VokabelEng, FVokabelListe.ValueFromIndex[i]) then begin Result := FVokabelListe.Names[i]; Exit; end; end; function TVokabel2.VokabelAnzahl: Integer; begin Result := FVokabelListe.Count; end; procedure TVokabel2.AllesSpeichern; begin FVokabelListe.SaveToFile(FFileName); end; function TVokabel2.GibZeigerVokabelDe(Zeiger: Integer): string; begin Result := ''; //sind Vokablen vorhenden? if FVokabelListe.Count = 0 then Exit; //beim Unterschreiten der unteren Grenze, weiter mit der höhsten Vokabel if Zeiger < 0 then Zeiger := FVokabelListe.Count - 1; //beim Unterschreiten der oberen Grenze, weiter mit der niedrigesten Vokabel if Zeiger > (FVokabelListe.Count - 1) then Zeiger := 0; FZeiger := Zeiger; Result := FVokabelListe.Names[FZeiger]; end; function TVokabel2.GibErsteVokabelDe: string; begin Result := GibZeigerVokabelDe(0); end; function TVokabel2.GibNaechsteVokabelDe: string; begin Result := GibZeigerVokabelDe(FZeiger + 1); end; function TVokabel2.GibVorherigeVokabelDe: string; begin Result := GibZeigerVokabelDe(FZeiger - 1); end; function TVokabel2.GibLetzteVokabelDe: string; begin Result := GibZeigerVokabelDe(FVokabelListe.Count - 1); end; function TVokabel2.GibVokabelDeIndex(VokabelDe: string): Integer; begin Result := FVokabelListe.IndexOfName(VokabelDe); end; procedure TVokabel2.LoescheVokabel(Index: Integer); begin FVokabelListe.Delete(Index); end; end. Hier noch ein Beispiel zum Testen:
Delphi-Quellcode:
uses
uListe; var VokabelListe: TVokabel2; procedure TForm1.FormCreate(Sender: TObject); begin VokabelListe := TVokabel2.Create(ChangeFileExt(ParamStr(0), '.txt')); end; procedure TForm1.FormDestroy(Sender: TObject); begin //Liste wird automatisch gesichert VokabelListe.Free; end; procedure TForm1.Button1Click(Sender: TObject); begin VokabelListe.VokabelNeu('Hund', 'dog'); VokabelListe.VokabelNeu('Katze', 'cat'); VokabelListe.VokabelNeu('Programmierer', 'programmer'); VokabelListe.VokabelNeu('Kaffee', 'coffee'); end; procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage(VokabelListe.GibErsteVokabelDe); end; procedure TForm1.Button3Click(Sender: TObject); begin ShowMessage(VokabelListe.GibNaechsteVokabelDe); end; procedure TForm1.Button4Click(Sender: TObject); begin ShowMessage(VokabelListe.GibVorherigeVokabelDe); end; procedure TForm1.Button5Click(Sender: TObject); begin ShowMessage(VokabelListe.GibLetzteVokabelDe); end; procedure TForm1.Button6Click(Sender: TObject); begin ShowMessage(VokabelListe.GibVokabelEng('katze')); end; procedure TForm1.Button7Click(Sender: TObject); begin ShowMessage(VokabelListe.GibVokabelDe('Coffee')); end; procedure TForm1.Button8Click(Sender: TObject); begin ShowMessage(IntToStr(VokabelListe.VokabelZeiger)); end; procedure TForm1.Button9Click(Sender: TObject); begin ShowMessage(IntToStr(VokabelListe.VokabelAnzahl)); end; procedure TForm1.Button10Click(Sender: TObject); begin ShowMessage(IntToStr(VokabelListe.GibVokabelDeIndex('Katze'))); end; procedure TForm1.Button11Click(Sender: TObject); var k: Integer; begin k := VokabelListe.GibVokabelDeIndex('Katze'); VokabelListe.LoescheVokabel(k); end; |
![]() |
Registriert seit: 11. Jun 2013 Ort: Frankfurt am Main 13 Beiträge FreePascal / Lazarus |
#3
Die Ansätze von SirRufo und Blup finde ich zwar persönlich sehr gut und gelungen, und es ist erfreulich, dass der TE die Aufgabe mit einer Klasse löst (auch wenn es noch Probleme gibt, die Richtung stimmt zumindest), aber ich glaube zu erkennen (ich kann mich aber auch irren), dass sich der TE etwas verloren hat. Vor allem als Anfänger kann es problematisch sein am Anfang gleich zwei Hürden zu meistern. Die eine Hürde ist die Klasse. Ich finde man sollte sich erst einer Aufgabe widmen, bis die sitzt. Andere Probleme lenken davon ab, wie z. B. die Hürde beliebige Daten zu speichern. Deshalb meine Idee mit TStringList. Das kennt fast jeder, denn das ist einer der ersten Klassen die man sich genauer anguckt.
@thejacensolo Ich hab gerade ein Beispiel geprogt. Betrachte das nicht als fertige Klasse, auch wenn sie funktioniert. Auf Sicherheitsabfrage, Fehlermeldungen usw. habe ich verzichtet, denn es ist deine Klasse. Ich hab nur ein Beispiel gemacht in dem ich verführe wie einfach diese Aufgabe mit TStringList gelöst werden kann. Den Rest mußt du alleine machten.
Delphi-Quellcode:
Kurz zu der Beschreibung: über Create wird ein Pfad angegeben und somit eine Textdatei mit Vokalen geladen. Beim Freigeben wird automatisch gespeichert. Man kann aber auch mit AllesSpeichern selbst speichern. Über VokabelNeu wird eine Vokabel angelegt. Über Parameter gibt man das deutsche und englische Wort. Über GibVokabelEng und GibVokabelDe kann man eine Vokabel abfragen. Mit GibErsteVokabelDe, GibNaechsteVokabelDe, usw. kann man sich rauf und runter deutsche Vokabeln geben lassen. Die Englische mit der Methode oben abgefragt.
unit uListe;
interface uses SysUtils, Classes; type TVokabel2 = class private FFileName: string; FZeiger: Integer; FVokabelListe: TStringList; function GibZeigerVokabelDe(Zeiger: Integer): string; public constructor Create(const FileName: string); destructor Destroy; override; procedure VokabelNeu(Deutsch, Englisch: string); procedure VokabelBearbeiten(Deutsch, Englisch: string); function GibVokabelEng(VokabelDe: string): string; function GibVokabelDe(VokabelEng: string): string; function VokabelAnzahl: Integer; property VokabelZeiger: Integer read FZeiger; procedure AllesSpeichern; function GibErsteVokabelDe: string; function GibNaechsteVokabelDe: string; function GibVorherigeVokabelDe: string; function GibLetzteVokabelDe: string; function GibVokabelDeIndex(VokabelDe: string): Integer; procedure LoescheVokabel(Index: Integer); end; implementation constructor TVokabel2.Create(const FileName: string); begin inherited Create; FFileName := FileName; FZeiger := 0; FVokabelListe := TStringList.Create; if FileExists(FFileName) then FVokabelListe.LoadFromFile(FFileName); end; destructor TVokabel2.Destroy; begin AllesSpeichern; FVokabelListe.Free; inherited Destroy; end; procedure TVokabel2.VokabelNeu(Deutsch, Englisch: string); begin FVokabelListe.Values[Deutsch] := Englisch; end; procedure TVokabel2.VokabelBearbeiten(Deutsch, Englisch: string); begin VokabelNeu(Deutsch, Englisch); end; function TVokabel2.GibVokabelEng(VokabelDe: string): string; begin Result := FVokabelListe.Values[VokabelDe]; end; function TVokabel2.GibVokabelDe(VokabelEng: string): string; var i: Integer; begin Result := ''; for i := 0 to FVokabelListe.Count - 1 do if SameText(VokabelEng, FVokabelListe.ValueFromIndex[i]) then begin Result := FVokabelListe.Names[i]; Exit; end; end; function TVokabel2.VokabelAnzahl: Integer; begin Result := FVokabelListe.Count; end; procedure TVokabel2.AllesSpeichern; begin FVokabelListe.SaveToFile(FFileName); end; function TVokabel2.GibZeigerVokabelDe(Zeiger: Integer): string; begin Result := ''; //sind Vokablen vorhenden? if FVokabelListe.Count = 0 then Exit; //beim Unterschreiten der unteren Grenze, weiter mit der höhsten Vokabel if Zeiger < 0 then Zeiger := FVokabelListe.Count - 1; //beim Unterschreiten der oberen Grenze, weiter mit der niedrigesten Vokabel if Zeiger > (FVokabelListe.Count - 1) then Zeiger := 0; FZeiger := Zeiger; Result := FVokabelListe.Names[FZeiger]; end; function TVokabel2.GibErsteVokabelDe: string; begin Result := GibZeigerVokabelDe(0); end; function TVokabel2.GibNaechsteVokabelDe: string; begin Result := GibZeigerVokabelDe(FZeiger + 1); end; function TVokabel2.GibVorherigeVokabelDe: string; begin Result := GibZeigerVokabelDe(FZeiger - 1); end; function TVokabel2.GibLetzteVokabelDe: string; begin Result := GibZeigerVokabelDe(FVokabelListe.Count - 1); end; function TVokabel2.GibVokabelDeIndex(VokabelDe: string): Integer; begin Result := FVokabelListe.IndexOfName(VokabelDe); end; procedure TVokabel2.LoescheVokabel(Index: Integer); begin FVokabelListe.Delete(Index); end; end. Hier noch ein Beispiel zum Testen:
Delphi-Quellcode:
uses
uListe; var VokabelListe: TVokabel2; procedure TForm1.FormCreate(Sender: TObject); begin VokabelListe := TVokabel2.Create(ChangeFileExt(ParamStr(0), '.txt')); end; procedure TForm1.FormDestroy(Sender: TObject); begin //Liste wird automatisch gesichert VokabelListe.Free; end; procedure TForm1.Button1Click(Sender: TObject); begin VokabelListe.VokabelNeu('Hund', 'dog'); VokabelListe.VokabelNeu('Katze', 'cat'); VokabelListe.VokabelNeu('Programmierer', 'programmer'); VokabelListe.VokabelNeu('Kaffee', 'coffee'); end; procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage(VokabelListe.GibErsteVokabelDe); end; procedure TForm1.Button3Click(Sender: TObject); begin ShowMessage(VokabelListe.GibNaechsteVokabelDe); end; procedure TForm1.Button4Click(Sender: TObject); begin ShowMessage(VokabelListe.GibVorherigeVokabelDe); end; procedure TForm1.Button5Click(Sender: TObject); begin ShowMessage(VokabelListe.GibLetzteVokabelDe); end; procedure TForm1.Button6Click(Sender: TObject); begin ShowMessage(VokabelListe.GibVokabelEng('katze')); end; procedure TForm1.Button7Click(Sender: TObject); begin ShowMessage(VokabelListe.GibVokabelDe('Coffee')); end; procedure TForm1.Button8Click(Sender: TObject); begin ShowMessage(IntToStr(VokabelListe.VokabelZeiger)); end; procedure TForm1.Button9Click(Sender: TObject); begin ShowMessage(IntToStr(VokabelListe.VokabelAnzahl)); end; procedure TForm1.Button10Click(Sender: TObject); begin ShowMessage(IntToStr(VokabelListe.GibVokabelDeIndex('Katze'))); end; procedure TForm1.Button11Click(Sender: TObject); var k: Integer; begin k := VokabelListe.GibVokabelDeIndex('Katze'); VokabelListe.LoescheVokabel(k); end; ![]() |
![]() |
Registriert seit: 28. Apr 2008 Ort: Stolberg (Rhl) 6.659 Beiträge FreePascal / Lazarus |
#4
Dann schau mal in die OH zu TStrings.
ValueFromIndex gibt von ![]() Hund=dog
Der kleinste Index ist 0 der größte Liste.count-1 Gruß K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |