Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Unicode-String im Record speichern (https://www.delphipraxis.net/170050-unicode-string-im-record-speichern.html)

Gagamba 28. Aug 2012 10:35


Unicode-String im Record speichern
 
Hallo,
ich stelle grade von Delphi7 auf Delphi9. Dabei gibt es jetzt (wie erwartet) Probleme mit Unicode bzw. Widestring.
einfaches Codebeispiel:

Delphi-Quellcode:
TYPE Datenrecord = RECORD
 Name : STRING;
 Jahr : INTEGER;
 END;
VAR AlleDaten : ARRAY [1..MaxDaten] OF Datenrecord;
Das Sichern/Laden geht standardmäßig über eine Datei
Delphi-Quellcode:
VAR Datenfile : FILE OF Datenrecord
die konventionell-sequentiell gelesen bzw. geschrieben wird

Unter Delphi9 wwerden die Strings allerdings nicht mehr in fixer Länge abgespeichert, sondern in ihrer tatsächlichen Länge, was dazu führt, dass die Dateigröße sich laufend ändert, und die Hintereinander-Schachtelung innerhalb des Arrays völlig durcheinander kommt!
Unter Delphi7 war String=Shortstring (wenn man ihn nicht umdefiniert hat), jetzt ist es zwingend Widestring. Da auch Chinesen Namen haben, sollte man den Widestring nutzen, also STRING lassen (sonst könnte man die Definition auf STRING[255] o.ä. ändern und hätte keine Probleme).
Wie löse ich das, ohne Texte und Daten voneinander trennen zu müssen? Eine Trennung stelle ich mir so vor, dass die Namen in einer TStringlist definiert werden, und auch mit deren Methoden gelesen und gesichert werden. Aber wie gesagt, möchte ich diese Trennung nicht machen..

Vielleicht isses ganz einfach, und ich steh nur auf dem Schlauch?

Besten Dank schonmal vorab: Gagamba

DeddyH 28. Aug 2012 10:40

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von Gagamba (Beitrag 1180276)
Unter Delphi7 war String=Shortstring (wenn man ihn nicht umdefiniert hat)

Wer sagt denn sowas? IIRC ist String schon ab Delphi 2 ein AnsiString, d.h. Dein Record hätte eigentlich nur den Zeiger auf den jeweiligen String enthalten dürfen, nicht aber den String selbst, es sei denn, Du deklarierst ihn als Shortstring. Was passiert denn, wenn Du aus den Strings ein WideChar-Array fester Länge machst?
Delphi-Quellcode:
Name: array[1..300] of WideChar;

himitsu 28. Aug 2012 10:56

AW: Unicode-String im Record speichern
 
Nur der Typ
Delphi-Quellcode:
String[nr]
ist ein ShortString mit Längenangabe und kein AnsiString.

Gagamba 28. Aug 2012 10:59

AW: Unicode-String im Record speichern
 
OK, ich hab mich falsch ausgedrückt: ich habe unter Delphi7 und früheren Versionen immer nur Shortstrings verwendet, auch innerhalb von gemischten Datenrecords. So kommt das Problem jetzt zu Stande. Ich möchte ja nicht einen Zeiger auf einen String abspeichern, sondern den Inhalt. Wenn ich nur den Zeiger abspeichere, dann geht der Inhalt ja für die nächste Sitzung verloren...
Danke soweit

Bernhard Geyer 28. Aug 2012 11:01

AW: Unicode-String im Record speichern
 
Wenn du keine Unicode-Strings hast ist doch die Lösung von himitsu das was du benötigst

mkinzler 28. Aug 2012 11:02

AW: Unicode-String im Record speichern
 
Das ist aber kein Problem von Unicode, sondern Bestand bei AnsiString ja auch schon. mach es wie Detlef es vorgeschlagen hat.

uligerhardt 28. Aug 2012 11:12

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von mkinzler (Beitrag 1180295)
Das ist aber kein Problem von Unicode, sondern Bestand bei AnsiString ja auch schon. mach es wie Detlef es vorgeschlagen hat.

Jein. Das Problem ist, das es kein Unicode-Äquivalent zu ShortString/string[N] gibt. Klar kann man mit WideChar-Arrays hantieren, aber die kann man halt nicht so einfach als Strings benutzen wie das mit ShortStrings ging (Zuweisungskompatibilität AnsiString <-> ShortString, automatisches Stutzen auf Maximallänge etc.).

p80286 28. Aug 2012 11:13

AW: Unicode-String im Record speichern
 
@himitsu und DeddyH
da gab es einen Compilerschalter der String=Ansistring oder String=Shortstring auswählen konnte.

Zitat:

Zitat von Bernhard Geyer (Beitrag 1180294)
Wenn du keine Unicode-Strings hast ist doch die Lösung von himitsu das was du benötigst

!!!!


Dann Nutz doch ein
Delphi-Quellcode:
Tunicodestring = record
                   lange : word;
                   ustr : array[1..255] of widechar;
                 end;
Gruß
K-H

Gagamba 28. Aug 2012 11:20

AW: Unicode-String im Record speichern
 
Richtigstellung:
ich hatte BISHER keinen Unicode-String, muss JETZT aber umstellen. Brauche also im Datenrecord einen speicherbaren Stringtyp, der Unicode-kompatibel ist.
Sollte das NICHT möglich sein (z.B. via Array .. of Char, da hab ich nicht den Durchblick, ob das wirklich 100% kompatibel ist zum Unicode-String) muss ich vermutlich(?!) numerische Daten von Textdaten trennen und die Textdaten via TStringlist und dessen Methoden lesen und schreiben.
Oder hat jemand eine andere und/oder bessere Idee?
Danke!

jfheins 28. Aug 2012 11:30

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von Gagamba (Beitrag 1180301)
Oder hat jemand eine andere und/oder bessere Idee?
Danke!

Du könntest gleich auf XML Dateien umstellen. Da hast du i.d.R. kein Problem mit Unicode und bist für zukünftige Erweiterungen gut gerüstet :)

Iwo Asnet 28. Aug 2012 11:35

AW: Unicode-String im Record speichern
 
Wenn man jedem Record eine LoadFrom/SaveTo-Stream Methode spendiert, hat man all diese Probleme doch nicht.
In dieser Methode lädt/speichert man einfach explizit jedes Feld einzeln.

himitsu 28. Aug 2012 11:41

AW: Unicode-String im Record speichern
 
Dann kannst'e aber auch gleich eine Klasse nutzen, wobei der Schreiben lesen auch sehr schön über die RTTI behandelt werden kann.


Für UnicodeStrings, bzw für längere AnsiStrings (> 255) in Records hatte ich mal fast für ab D2006/TDE veröffentlicht.

Also ein Records mit Array[..] of XxxChar, welcher mit Operatoren so aufgemotzt wurde, damit er sich wie ein normaler String nutzen läßt.

Iwo Asnet 28. Aug 2012 11:51

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von himitsu (Beitrag 1180309)
Dann kannst'e aber auch gleich eine Klasse nutzen

Richtig, muss man aber nicht. Als reines DTO hat ein Record den kleineren Footprint (wissen wir ja).

uligerhardt 28. Aug 2012 11:52

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von himitsu (Beitrag 1180309)
Für UnicodeStrings, bzw für längere AnsiStrings (> 255) in Records hatte ich mal fast für ab D2006/TDE veröffentlicht.

Also ein Records mit Array[..] of XxxChar, welcher mit Operatoren so aufgemotzt wurde, damit er sich wie ein normaler String nutzen läßt.

Findest du da noch nen Link dazu? Vor dem Problem stehen wir nämlich auch in absehbarer Zeit.

Gagamba 28. Aug 2012 12:46

AW: Unicode-String im Record speichern
 
Hallo,
xml kommt eigentlich nicht in Frage, damit werden manche Dateien riesig und unhandlich.
Siegfried

Iwo Asnet 28. Aug 2012 12:47

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von Gagamba (Beitrag 1180326)
xml kommt eigentlich nicht in Frage, damit werden manche Dateien riesig und unhandlich.

Mit JSON passiert das nicht.

mkinzler 28. Aug 2012 12:49

AW: Unicode-String im Record speichern
 
Zudem düftre es nicht viel mehr ergeben, wie eine reine Textdatei; dabei aber besser lesbar sein.

Gagamba 28. Aug 2012 12:51

AW: Unicode-String im Record speichern
 
aha, und was ist JSON?
ich gebe zu bedenken, dass manche Dateien tausende von numerischen variablen (die Texte sind ja nur eine Ausnahme) enthalten, somit auch tausende von zeilen innerhalb der xml-datei zu verwalten wären - ganzh zu schweigen von der womöglich schwachen Genauigkeit, wenn man real-zahlen alphanumerisch speichert..
Gagamba

himitsu 28. Aug 2012 12:54

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von uligerhardt (Beitrag 1180312)
Findest du da noch nen Link dazu? Vor dem Problem stehen wir nämlich auch in absehbarer Zeit.

So auf die Schnelle nicht.

Müste mal sehn, wie schnell ich daheim eine Unit wiederfinde, wo ich das verwendete, um hier über den Typenbezeichner suchen zu können.

DeddyH 28. Aug 2012 12:54

AW: Unicode-String im Record speichern
 
JSON, Parser dafür sollten sich im Internet finden lassen.

Iwo Asnet 28. Aug 2012 12:56

AW: Unicode-String im Record speichern
 
Du kannst auch binär speichern, wenn es auf die Größe ankommt. Wenn Du beide Seiten selbst implementierst, dann würde ich das Binärformat bevorzugen, da jedes Record/Klasse mit ihren LoadFrom/SaveToStream-Methoden und geeigneter Testungebung ausreichend robust ist.

Eine Delphi-Implementierung findest Du z.B. hier

uligerhardt 28. Aug 2012 13:00

AW: Unicode-String im Record speichern
 
Zitat:

Zitat von himitsu (Beitrag 1180330)
Zitat:

Zitat von uligerhardt (Beitrag 1180312)
Findest du da noch nen Link dazu? Vor dem Problem stehen wir nämlich auch in absehbarer Zeit.

So auf die Schnelle nicht.

Müste mal sehn, wie schnell ich daheim eine Unit wiederfinde, wo ich das verwendete, um hier über den Typenbezeichner suchen zu können.

Wäre toll, wenn du was findest. Meine bisherigen Experimente dazu waren nicht von großem Erfolg gekrönt. Allerdings hatte ich auch den Anspruch, das Ding nicht ausschließlich für Stringlänge 255 zu bauen und habe versucht, das mit Generics-Tricksereien zu lösen (so a la
Delphi-Quellcode:
MyString50: TFixedUnicodeString<string[50]>;
). Blöde Idee. :mrgreen:

himitsu 28. Aug 2012 13:15

AW: Unicode-String im Record speichern
 
Ich hatte es auch versucht mit den Generics zu kreuzen, aber leider kann man die nicht wie Makros verwenden, bzw. man kann keine generischen Konstanten mitgeben.

Quasi
Delphi-Quellcode:
TMyString<50>
, wo dann intern ein
Delphi-Quellcode:
array[0..50-1] of char
dekalriert wird. :cry:

Im Prinzip bestand es halt aus soeinem Array, in einem Record verpackt und dazu noch ein paar implizite und explizite Operatoren von und zu AnsiString, WideStringund zuletzt auch noch UnicodeString, welche das Array entsprechend mit einem #0-terminierten String füllten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:35 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz