![]() |
AW: Eine lineare Liste an Strings als Datei speichern
@Popov
Das Array ist nur ein Überbleibsel (Artefakt). Die Vokabeln werden doch über die Klasse
Delphi-Quellcode:
verwaltet.
TListe
Somit muss nur noch die Listen-Instanz gespeichert bzw. geladen werden :) |
AW: Eine lineare Liste an Strings als Datei speichern
@Sir Rufo
Da mußt du mir weiter helfen. Vielleicht sehe ich nur nicht vor lauter Bäume den Wald nicht mehr, aber ich weiß nicht so richtig was du meinst. In TListe gibt es einige Methoden. Guckt man sich die oberflächlich an, wie ich es anscheinend gemacht habe, entdeckt man dort die Klasse TVokabel. Auf die wird verschiedenartig zugegriffen. Ich kann mich auch täuschen, aber hier wird meiner Meinung nach die Klasse als Record genutzt. Berichtige mich wenn ich mich verguckt habe. Beispiel TListe.hinzufuegen. Mit TVokabel.initvok wird ein neueVok Objekt erstellt. Mit Erste.Naechste := neueVok wird wohl die Adresse übergeben. So langsam verliere ich da aber schon den Überblick. |
AW: Eine lineare Liste an Strings als Datei speichern
Zitat:
|
AW: Eine lineare Liste an Strings als Datei speichern
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; |
AW: Eine lineare Liste an Strings als Datei speichern
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; |
AW: Eine lineare Liste an Strings als Datei speichern
Zitat:
|
AW: Eine lineare Liste an Strings als Datei speichern
Dann schau mal in die OH zu TStrings.
ValueFromIndex gibt von Zitat:
Der kleinste Index ist 0 der größte
Delphi-Quellcode:
Gruß
Liste.count-1
K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz