[gelöst] typed files mit beliebig langen strings?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

[gelöst] typed files mit beliebig langen strings?

Beitrag von mulcheo »

Hi,

in meinem Prog. soll der user die Möglichkeit haben, einzelne Wörter und Zeilen eines Textes zu kommentieren. Die Einträge werden in einer Datei abgelegt. Ich definiere also:

Code: Alles auswählen

 
type
  Kommentar = record
    Zeile: Integer;
    Wort: Integer;
    Bemerkung: string;
  end;
nun zwingt mich Lazarus aber ("Error: Typed files cannot contain reference-counted types.") dem string eine Länge zuzuweisen - bsp. string[255]. Mein Problem ist nun, dass ich im Voraus einfach nicht sagen kann, wie groß der String sein wird (1-2 Seiten Text? 30 chars, wie auch immer...).

Wie umgehe ich dieses Problem? Klar, ne zweite text-file wäre technisch möglich, aber dann habe ich einen riesigen Aufwand, wenn es darum geht, die beiden files synchron zu halten (wenn beispielsweise der Eintrag in der typed-file verändert, gelöscht oder erweitert wird usw..)

Danke schonmal :>

[update: (Juni 214)] ich habe mich nun doch in die Filestreams eingearbeitet - ist langfristig die sauberste Lösung
Zuletzt geändert von mulcheo am So 29. Jun 2014, 22:04, insgesamt 2-mal geändert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: typed files mit beliebig langen strings?

Beitrag von Michl »

Ich sehe, da nicht wirklich viele Möglichkeiten:

1. Wie geschrieben, "Kommentarlänge" zu definieren, z.B. max 200 Zeichen "Bemerkung:String[200]". Allerdings wird in der Datei dann immer die 200 Stellen "Platz gehalten", egal, ob der Kommentar='' oder Kommentar.length=200 ist!

2. Record nicht als "File of Record" speichern, sondern z.B. ".txt" (Speichern -> Record in String umwandeln, Separator definieren, Einlesen -> Separator gibt Länge der Recordvariable an -> StrToRecord.Teil). Evtl. könnte man dafür auch eine fertige typisierte Datei z.B. ".xml" nehmen, man müsste da dann allerdings den Record in die Daten dieser typisierten Datei umwandeln.

3. Verwendung einer Datenbank

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: typed files mit beliebig langen strings?

Beitrag von mschnell »

Ich denke, am einfachsten definierst Du ein Fluchtsymbol, da im normalen Text nicht vorkommen darf. Nach dem Fluchtsymbol folgt dann der "Kommentar", der dann z.B. mit einem (u.U. anderen) Fluchtsymbol angeschlossen wird.

Beim "normalen" Anzeigen des Textes musst Du natürlich die Kommentare entfernen. Dabei kann die TStrinList "Komma" Funktion helfen.

-Michael

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: typed files mit beliebig langen strings?

Beitrag von Michl »

mschnell hat geschrieben:Ich denke, am einfachsten definierst Du ein Fluchtsymbol, da im normalen Text nicht vorkommen darf. Nach dem Fluchtsymbol folgt dann der "Kommentar", der dann z.B. mit einem (u.U. anderen) Fluchtsymbol angeschlossen wird.

Beim "normalen" Anzeigen des Textes musst Du natürlich die Kommentare entfernen. Dabei kann die TStrinList "Komma" Funktion helfen.

-Michael
Das stimmt, hilft aber dem OP sofern nicht weiter, dass er alle Kommentare auch wieder in einer separaten Datei speichern muss, wo er nicht weiss, wie lang der jeweilige Kommentar ist, es sei denn er typisiert die Datei (Ausgangsproblem).

Außerdem sollte noch erwähnt werden, dass nach dem "Fluchtsymbol" ein Link oder eine IP folgen muss, damit der jeweilige Kommentar eindeutig zugeordnet werden kann.

Eine Speicherung dieser IPs könntest du mit einer Textdatei realisieren, in der du eine IP mit einer fixen Länge als erstes speicherst, dann den Kommentar:
Pseudocode:
write(f,IP);
writeln(f,Kommentar);
Somit könntest du die IPs (oder auch dein Record) zeilenweise in eine Textdatei speichern. Beim Auslesen brauchst du nur die IP am Anfang vom String entfernen und du hast den Kommentar. Achtung im Kommentar selber dürften dann keine Zeilenumbrüche stattfinden!!!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: typed files mit beliebig langen strings?

Beitrag von Scotty »

Wie wäre es mit einem "Text:array of char/widechar" plus "NumberOfChars:longword"?

gocher
Beiträge: 298
Registriert: Di 23. Nov 2010, 23:41
OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
CPU-Target: 32Bit/64Bit
Wohnort: Geldern
Kontaktdaten:

Re: typed files mit beliebig langen strings?

Beitrag von gocher »

Also ich würde es so angehen:

Code: Alles auswählen

type
  Kommentar = record
    Zeile: Integer;
    Wort: Integer;
    Bemerkung: Integer; //Index der TList oder array Element
  end;
  Kommentare: array of Kommentar;
  Bemerkungen: TList; //oder array of string
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

Benutzeravatar
theo
Beiträge: 10873
Registriert: Mo 11. Sep 2006, 19:01

Re: typed files mit beliebig langen strings?

Beitrag von theo »

Ich würde das mit TStream machen.
Dort gibt es auch schon die Proc. WriteAnsiString http://www.freepascal.org/docs-html/rtl ... tring.html

P.S. DataPacker ginge auch: http://www.lazarusforum.de/viewtopic.php?p=2108#p2108

Code: Alles auswählen

var DP:TMemoryDataPacker;
begin
DP:=TMemoryDataPacker.create;
DP.AddString('Hello World');
DP.AddInt(1234);
DP.AddString('Bye World');
DP.Stream.SaveToFile('test.dat');
DP.free;
 
DP:=TMemoryDataPacker.create;
DP.Stream.LoadFromFile('test.dat');
Writeln(DP.GetString);
Writeln(DP.GetInt);
Writeln(DP.GetString);
DP.free;  

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: typed files mit beliebig langen strings?

Beitrag von mulcheo »

Auf TStream war ich bin meiner Recherche auch öfter schon gestoßen, leider fehlt mir da jedes Vorwissen. Wenn ich aber die Zeit finde, mich nochmals tiefer in das Thema einzuarbeiten, schau ich da auf jeden Fall mal rein. Ich habe mich jetzt tatsächlich dafür entschieden, die stringlastigen Teile in eine Textfile auszulagern und mir Fluchtsymbole zu definieren. Die Routinen dazu funktionieren auch schon, so dass das Problem damit (mehr oder minder unelegant) gelöst ist.

Das Problem mit dem Zeilenumbruch bleibt natürlich: Wenn das Memo (mein Eingabefeld) selbst schon Zeilenumbruch generiert muss ich ja darauf reagieren können... Ich kann nun alle Zeilen des Memo auslesen und zunächst zu einem string zusammenketten, dann sind die künstlichen Zeilenumbrüche wieder einkassiert aber leider auch alle, die vom User (via Enter) selbst kommen. Hat jemand noch eine elegante Idee, wie ich zwischen den Memo- und den User-generierten 'Zeilenumbrüchen' unterscheiden kann?

[edit]: hat sich als Pseudoproblem entpuppt. Mit Memo1.Lines.SaveToFile(); macht er die Unterscheidung automatisch :>
Zuletzt geändert von mulcheo am So 18. Aug 2013, 11:15, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10873
Registriert: Mo 11. Sep 2006, 19:01

Re: typed files mit beliebig langen strings?

Beitrag von theo »

Du bist einfach mMn auf dem Holzweg. Mach's mit TStream oder TMemoryDataPacker (s.oben).
Mit Fluchtsymbolen und sonstigem Krampf würde ich mich nicht länger aufhalten.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: typed files mit beliebig langen strings?

Beitrag von mschnell »

theo hat geschrieben:I
Writeln(DP.GetString);
Writeln(DP.GetInt);
Writeln(DP.GetString);
Dann sind die "int" Werte quasi die Fluchtsymbole.

Wie teilt TStream einem denn mit ob der nächste Wert ein String oder ein int (oder was auch immer) ist, damit man beim lesen die korrekte Abfolge einhält ? ?

-Michael

Benutzeravatar
theo
Beiträge: 10873
Registriert: Mo 11. Sep 2006, 19:01

Re: typed files mit beliebig langen strings?

Beitrag von theo »

mschnell hat geschrieben: Wie teilt TStream einem denn mit ob der nächste Wert ein String oder ein int (oder was auch immer) ist, damit man beim lesen die korrekte Abfolge einhält ? ?
Das Beispiel oben ist für den Datapacker. Es liest einen String, dann einen Integer und noch einen String.
TStream teilt einem gar nichts mit, das muss man so auslesen wie man's reingeschrieben hat, wie bei File of Record auch.
Er kann aber u.A. einen beliebig langen String speichern und lesen mit WriteAnsiString und ReadAnsiString.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: typed files mit beliebig langen strings?

Beitrag von mschnell »

theo hat geschrieben:TStream teilt einem gar nichts mit, das muss man so auslesen wie man's reingeschrieben hat, wie bei File of Record auch.
Er kann aber u.A. einen beliebig langen String speichern und lesen mit WriteAnsiString und ReadAnsiString.
OK. TStream ist ja sowieso virtuell und nur seine Nachkommen sind lebendig (z.B. TMemoryStream, TFilestream , ...) Es könnte also TStream Ableitungen geben - oder man könnte eine machen - , die eine solche Funktionalität haben. TDataPacker bietet dafür offensichtlich schon den größten Teil der notwendigen Software.

Genau das könnte sein, was hier gebraucht wird.

-Michael

Antworten