Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Lange Strings im Record (https://www.delphipraxis.net/131283-lange-strings-im-record.html)

oldmann 22. Mär 2009 08:57


Lange Strings im Record
 
Hallo,

gibt es in Delphi eine Möglichkeit in einem Record einen längeren String als 255 Zeichen zu benutzen.
Ich arbeite mich Delphi 6 Prof.

Mit freundlichen Grüssen,
Oldmann

himitsu 22. Mär 2009 09:15

Re: Lange Strings im Record
 
Eigentlich sollte es möglich sein, nur liegen dann die Textdaten nicht im Record, sondern im Record ist nur ein 4-Byte-Zeiger auf den Text enthalten.

direkt im String ginge nur ein Char-Array

Delphi-Quellcode:
Type TMyRec = Record
    String1: String;
    String2: AnsiString;
    Text1: Array[1..1024] of AnsiChar;
    Text2: Array[0..1023] of Char;
  End;
das sind beides sozusagen strings mit je maximal 1024 Zeichen.

String1 und String2: hier wären halt nir die Zeiger im Array und der Rest irgendwo anders.

Text1:
- Index 1 bis 1024 mach ich lieber so, da es so mit der Indizierung eines Strings übereinstimmt
- AnsiChar entspricht in D6 noch dem Char, aber in D2009 wäre Char=WideChar
und damit es dort keine Probleme gibt, nutz da lieber direkt AnsiChar

Text2:
- Index 0 bis 1024 würden viele nehmen, da die dymaischen Array und vieles andere mit dem Index 0 beginnt

alzaimar 22. Mär 2009 09:16

Re: Lange Strings im Record
 
Natürlich geht das. Du möchtest deinen Record aber bestimmt auch abspeichern. Da wird das dann etwas komplizierter. Sag mal, was du machen willst.

oldmann 22. Mär 2009 09:45

Re: Lange Strings im Record
 
Hallo,

hier ist ein Beispiel:
Es geht z. B. um folgenden Record:
Delphi-Quellcode:
 type
   Dateien=record
   Gegenstand,Raum,bemerk:string[25];
   preis:double;
   Anzahl:Integer;
   gekauft_am:string[10];
   identnr,bild:String[15];
   bemerkung:String[255];
 end;

Das ganze wird dann als Datensatz gespeichert.

Ausgegeben wird das dann in ein Stringgrid z. B. So:

     assignfile(hrdat,lpf+'Datei.dat');
     reset(hrdat);
     while not eof (hrdat) do
     begin
         read(hrdat,daten);        
        StringGrid1.cells[0,reihe]:=daten.gegenstand;
        StringGrid1.cells[1,reihe]:=daten.raum;
        ….usw.
     end;
     closefile(hrdat);
Das Feld 'Bemerkung' wird unter dem Stringgrid in eine Memo ausgegeben.
Ich möchte aber das Feld 'Bemerkung' grösser haben das mehr Daten eingegeben werden können.
Wie kann ich das anstellen.

Gruß Oldmann

quendolineDD 22. Mär 2009 10:12

Re: Lange Strings im Record
 
Vielleicht könntest du noch die Delphi-Tags setzten, damit dein Code lesbarer wird.
Wenn du einen String mit 255 Zeichen vorgibst, und ihn verlängern möchtest, dann solltest du die Zahl erhöhen ;-)

oldmann 22. Mär 2009 10:24

Re: Lange Strings im Record
 
Hallo,

nach meiner Kenntnis kann ein String in einem Record nur max. 255 Zeichen enthalten.
Wenn ich die Zahl einfach erhöhen könnte, hätte ich das Problem nicht.
Gruss Oldmann

mkinzler 22. Mär 2009 10:28

Re: Lange Strings im Record
 
Ein ShortString kann nur maximal 255 Zeichen lang werden. Bei einem AnsiString besteht diese Beschränkung nicht

oldmann 22. Mär 2009 10:42

Re: Lange Strings im Record
 
hallo mkinzler,

Leider kenne ich mich mit Ansistrings nicht aus.
Wenn ich hinter 'Bemerkung:Ansistring' setze kommt ein Fehlermeldung:
'Benötigt Finalization, nicht inm Dateityp erlaubt.'
Wie muss ich einen Ansistring deklarieren?

Gruss Oldmann

mkinzler 22. Mär 2009 10:46

Re: Lange Strings im Record
 
Genauso. Allerdings ist dieser dann 0-terminiert, d.h. hat keine feste Länge und kann deshalb nicht in einer typisierten Datei verwendet werden. Du musst, wie oben beschrieben auf einen Char Array ausweichen.

SirThornberry 22. Mär 2009 10:49

Re: Lange Strings im Record
 
@oldman: Könntest du bitte noch die Delphitags setzen. Dazu einfach auf http://www.delphipraxis.net/template.../icon_edit.gif über dem entsprechenden Beitrag klicken und dann den Beiträg entsprechend ändern. :)

himitsu 22. Mär 2009 10:51

Re: Lange Strings im Record
 
joar, Delphi achtet da zumindestens schön drauf ^^

aber das es sich um einen Record für eine Datei handelt, hättest du schon sagen müssen.

solange du mit den "alten" Pascal-Functionen arbeitest, ist für die das Char-Array die einzige Möglichkeit.

bei z.B. TSream-Nachkommen könnte man String/AnsiString verwende, müßte aber den Stringinhalt selbst speichern (z.B. als String mit abschließender #0, zur Begrenzung
oder indem man die Stringlänge vorher mit speichert ... beispiele gibt's da genügend im Forum)

oldmann 22. Mär 2009 11:24

Re: Lange Strings im Record
 
Hallo Leute,
das sind ja viele Antworten auf einmal.
Erst einmal danke dafür.
Erste Frage: Was sind Delphi Tags?
Wenn ich das bisher richtig verstanden habe wird es nur wie im ersten Beitrag beschrieben mit:
'bemerkung:Array[1..1024] of AnsiChar;' gehen.
Da ich mich damit überhaupt nicht auskenne wäre ich Euch für ein wenig Hilfestellung dankbar.
Wie speichere ich ein solches Array in meiner typisierten Datei?
Wie lesen ich das Array wieder aus der Datei aus und zeige es in einem Memo an?

Ich wäre Euch für ein paar Beispiele, die auch ich verstehen kann, dankbar.

Gruss Oldmann

Satty67 22. Mär 2009 11:33

Re: Lange Strings im Record
 
Über dem Editor-Fenster hier im Forum gibt es den Button "Delphi-Code". Cursor vor den Code setzen "Klick" und dann Cursor ans Ende des Code "Klick". Du siehst dann wie die Tag's aussehen und kannst die später auch manuell setzen.

In deinem Record ersetzt Du einfach String[255] durch Array[1..1024] of AnsiChar. Der Rest bleibt so wie es war...

Einfach mal ausprobieren, wenn Du eine Stelle hast, wo der Austausch Probleme macht, einfach nochmal gezielt nachfragen.

himitsu 22. Mär 2009 11:39

Re: Lange Strings im Record
 
Zitat:

Zitat von Satty67
Über dem Editor-Fenster hier im Forum gibt es den Button "Delphi-Code". Cursor vor den Code setzen "Klick" und dann Cursor ans Ende des Code "Klick".

oder Code markieren ein dann nur einmal auf den Button klicken :stupid:


Ach ja ... nur zum Verständnis: (bis D2007)

String = AnsiString
String[x] = ShortString

und ein ShortString kann nur 0 bis 255 Zeichen enthalten, da er für die Längenangabe ein Byte Verwendet.

Luckie 22. Mär 2009 11:52

Re: Lange Strings im Record
 
Mach aus dem Record eine Klasse. In der Klasse kannst du dann eine Metohde implementieren zum Speichern der Felder. Das wäre dann auch eine saubere OOP Lösung. Als Datenformat würde ich dann, wenn es nicht viele Daten sind eine Ini-Datei nehmen oder, wenn es ein paar mehr Daten sind, eine XML-Datei.

Satty67 22. Mär 2009 12:02

Re: Lange Strings im Record
 
Ob das oldman's aktuelle Fähigkeiten nicht übersteigt? Er sollte es lernen (früher als z.B. ich), aber ein Erfolgserlebnis mit seinem aktuellen Code ist auch ganz schön.

Luckie 22. Mär 2009 12:18

Re: Lange Strings im Record
 
Ich weiß nicht, wie weit fortgeschritten oldman ist. Aber eventuell hilft es ja anderen die weiter fortgeschritten sind und vor dem gleichen Problem stehen.

Es heißt übrigens "oldmans". Im deutschen gibt es das besitzanzeigende Apostroph nicht. ;)

Satty67 22. Mär 2009 13:07

Re: Lange Strings im Record
 
Ok, OK... sah für mich wohl bei dem englischen Wort einfach besser aus :stupid:

Ich hab' mir schon ein paar kleine Klassen gebastelt (seit der letzten Aufforderung hier im Forum). Klappt auch so langsam ganz gut. Den praktischen Nutzen bei bestimmten Aufgaben (besonders wenn Daten im Spiel sind) weis ich inzwischen auch zu schätzen.

Luckie 22. Mär 2009 13:29

Re: Lange Strings im Record
 
Na ja, der Vorteil eine Klasse ist eben, dass man die Daten und die Methoden, die diese Daten manipulieren, zusammen hat.

oldmann 22. Mär 2009 16:06

Re: Lange Strings im Record
 
Hallo Leute,
das sind viele Antworten.
Erst einmal danke dafür.
Allerdings hatten die letzten 4 Antworten überhaupt nichts mehr mit dem Thema zu tun.
Mein Problem ist bisher nicht gelöst.
Also frage ich noch einmal.
Bisher habe ich verstanden das ich die Variable 'bemerkung' im Record als 'Array[1..1024] of AnsiChar' benennen muss.
Da ich mich damit überhaupt nicht auskenne wäre ich Euch für ein wenig Hilfestellung dankbar.
Wie speichere ich ein solches Array in meiner typisierten Datei?
Wie lesen ich das Array wieder aus der Datei aus und zeige es in einem Memo an?


Es wird doch unter Euch sicher Experten geben die mir hier weiterhelfen können.

Ich wäre Euch für ein paar Beispiele, die auch ich verstehen kann, dankbar.

Gruss Oldmann

alzaimar 22. Mär 2009 16:59

Re: Lange Strings im Record
 
Bei langen Strings kannst Du die Daten nicht in einer typisierten Datei speichern. Das Wesen der typisierten Datei ist ja, das sie aus Datensätzen konstanter Größe besteht. Das wäre hier mit den dynamischen und (fast) beliebig langen Strings nicht mehr gegeben.

Wenn Du deine langen Strings auf ein 'Array [0..X] Of Char' beschränkst, wird es funktionieren (oder ein Array [..x] Of String[255]), sonst musst du dir etwas anderes ausdenken.

Vielleicht solltest Du dich mit Datenbanken oder alternativen Datenformaten beschäftigen. Hier würde eine klitzekleine Datenbank reichen, für die nur rudimentäre Kenntnisse erforderlich sind. Falls Du ein Office-Paket dein Eigen nennst, kannst du es mit Access versuchen. Das ist im Einzelplatzbetrieb ausreichend robust. Vorteil: Nix runterladen, nix installieren, wenig lernen.

Noch einfacher wäre das TClientDataset, das es erlaubt, eine Tabelle in einer Textdatei zu speichern/laden. Ich bin mir jedoch nicht sicher, ob Du das in deinem Delphi6Prof hast.

Eine weitere Möglichkeit wäre eine TkbMemTable, das ist ein Dataset, das komplett im Speicher liegt, sich aber auch in eine Datei speichern bzw. aus ihr laden lässt. Eine TkbMemTable-Komponente findest Du hier. Die Standard-Version ist wohl kostenlos.

Einige sehr interessante Möglichkeiten habe ich bei www.Torry.net gefunden. Ihnen Allen ist gemein, das sie Dir die Problematik des Abspeicherns abnehmen.

Wenn Du unbedingt bei deinem Record-Konzept und typisierten Dateien bleiben willst, solltest Du das Lesen und Schreiben eines Datensatzes als Record-Methode implementieren und dort festlegen, wie Du mit langen Strings umgehst. Eine Möglichkeit wäre doch, die langen Texte in einer zweiten Datei zu speichern und im Record nur die Verweise (Index oder ID) des Strings.

Ich würde die TDataset-Variante ins Auge fassen, sofern die Komponente BLOBS (Memo-Felddatentyp) unterstützt.

oldmann 22. Mär 2009 18:26

Re: Lange Strings im Record
 
Hallo alzaimar,

danke für Deine ausführliche Antwort.
Du hast viele Möglichkeiten aufgezählt die aber alle irgendwo einen Haken haben.
Datenbank kann ich überhaupt nicht und ich glaube das ich das auf meine alten Tage wohl auch nicht mehr lerne.
Komponenten z. B. von Torry sind auch problematisch da ich kein Englisch kann.
Da Du ja auch sagst das z.B. ein 'Array[1..1024] of AnsiChar' in einer typisierten Datei gehen würde brauchte ich nur noch jemanden der mir das möglichst an einem Beispiel erklären kann.
Also:
Wie speichere ich ein solches Array in meiner typisierten Datei?
Wie lesen ich das Array wieder aus der Datei aus und zeige es in einem Memo an?

Das wird doch wohl jemand von Euch wissen.
Ich hoffe es jedenfalls.

Mit freundlichen Grüssen,
E.Werner

Satty67 22. Mär 2009 18:54

Re: Lange Strings im Record
 
Du speicherst doch schon die ganze Zeit Deine Record's oder hab' ich das falsch verstanden.

Hier Dein eigenes Beispiel für READ:
Delphi-Quellcode:
assignfile(hrdat,lpf+'Datei.dat');
     reset(hrdat);
     while not eof (hrdat) do
     begin
       read(hrdat,daten);        
       StringGrid1.cells[0,reihe]:=daten.gegenstand;
       StringGrid1.cells[1,reihe]:=daten.raum;
       ….usw.
     end;
     closefile(hrdat);
Du tauscht nur ein Element in Deinem Record aus, so wie schon beschrieben:
Delphi-Quellcode:
// alte Version
type
   Dateien=record
   Gegenstand,Raum,bemerk:string[25];
   preis:double;
   Anzahl:Integer;
   gekauft_am:string[10];
   identnr,bild:String[15];
   bemerkung:String[255];
end;
// neue Version
type
   Dateien=record
   Gegenstand,Raum,bemerk:string[25];
   preis:double;
   Anzahl:Integer;
   gekauft_am:string[10];
   identnr,bild:String[15];
   bemerkung: array[1..1024] of AnsiChar;
end;
Jetzt nicht aufhören zu lesen, hier folgt noch eine wichtige Informationen ;)

Dein Record ist jetzt größer, also passen die Daten aus der alten Datei nicht mehr! Wenn es noch keine wichtigen Daten gab, einfach eine neue Datei anlegen. Gibt es in der alten Datei schon wichtige Daten, muss die "konvertiert" werden.

Mit dem alten Record wie gewohnt einlesen... die Daten dem neuen Record zuweisen und in einer neuen Datei mit anderem Namen speichern (das mit allen Records machen).

oldmann 22. Mär 2009 20:38

Re: Lange Strings im Record
 
Hallo Satty67,

danke für Deine Antwort.
So wie Du es geschrieben hast hatte ich meinen Record schon geändert.
Da noch keine Daten vorhanden waren, war das auch kein Problem.
Wie schon weiter vorn schrieb, taucht das Problem beim zuweisen der von Anwender eingegebenen Daten auf.
Wenn der Anwender seinen Text in die Memo schreibt und ich diesen Text zum speichern der Variable 'Datei.bemerkung:=Memo1.Text' zuweise dann kommt eine Fehlermeldung 'Inkompatible Typen Array und TCaption'.
Das heisst, dass ich nicht so einfach dem Array 'Datei.bemerkung den Text aus Memo1 zuweisen kann.
Deshalb meine Fragen an die Experten, die ich übrigends schon drei mal hier gestellt habe, aber keiner beantwortet sie:
Wie weise ich dem Array 'Datei.bemerkung den Text aus Memo1 zu?
Wie speichere ich ein solches Array in meiner typisierten Datei?
Wie lesen ich das Array wieder aus der Datei aus und zeige es in einem Memo an?


Es wird doch sicher Experten geben die mir hier weiterhelfen können.
Oder sollte ich mich hier irren.
Ich wäre Euch für ein paar Beispiele, die auch ich verstehen kann, dankbar.

Gruss Oldmann

Satty67 22. Mär 2009 20:49

Re: Lange Strings im Record
 
Ich lese halt immer wieder: Wie speichere ich ein solches Array in meiner typisierten Datei?

Die Frage: Wie weise ich dem Array 'Datei.bemerkung den Text aus Memo1 zu? lese ich jetzt zum ersten mal... da hab' ich wohl nicht aufgepasst.

alzaimar 22. Mär 2009 21:06

Re: Lange Strings im Record
 
Delphi-Quellcode:
Type
  TDaten = Record
    Irgendwas : integer;
    LangerString : array [0..1023] Of Char; // oder länger
  End;


Var
  Datei : File Of TDaten;
  sHilfsString : String;

...
// Laden
  Read (Datei, Daten);
// Schreiben
  Write (Datei, Daten);

// in Memo reinpacken
  Memo1.Lines.Add (Daten.LangerString);

// aus Memo lesen
  StrLCopy (@Daten.LangerString, PChar (Memo1.Lines.Text), SizeOf (Daten.LangerString));

oldmann 23. Mär 2009 12:26

Re: Lange Strings im Record
 
Hallo alzaimar,

danke für Deine Antwort.
Ich bin begeistert, es klappt.
Eine Frage habe ich noch. was bedeutet das T bei TDaten = Record?
Ist vielleicht ne dumme Frage, aber ich weiss es nicht.
Ich möchte mich bei Dir und natürlich auch bei allen anderen die sich die Mühe gemacht haben auf meine laienhaften Fragen zu antworten, ganz herzlich bedanken.

Mit freundlichen Grüssen,
Oldmann :hi:

Cyf 23. Mär 2009 12:38

Re: Lange Strings im Record
 
Das vorgestellt T bei Records, Klassen und Enums ist eine Konvention, um diese Typen leichter zu erkennen.

oldmann 23. Mär 2009 12:48

Re: Lange Strings im Record
 
Hallo Cyf,

danke für Deine Antwort.

Gruss Oldmann


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 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