Thema: Delphi Unicode in Textfiles...

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#1

Unicode in Textfiles...

  Alt 20. Feb 2006, 16:24
Ich mach das jetzt einfach mal öffentlich (denke nicht, daß PAX was dagegen haben wird),
damit auch mal andere mitreden, oder auch was davon haben können

Zitat von PAX (per PN):
Zitat:
Die TNT-Controls seh'n nicht schlecht aus. Und wenn ich mich entscheiden muss, werd' ich wohl bei NT bleiben. (arbeite selbst mit 2000P)

Nach Möglichkeit versuche ich aber so zu arbeiten, das es unter 95 bis XP (demnächst natürlich auch Longhorn) läuft.
Auf der HomePage werden zusätzlich noch downloadbare Schriftarten eingebunden, so das man auch ohne die entsprechende Sprachunterstützung was erkennt.
Es ist schon richtig schwer etwas so zu schreiben, das es bei möglichst vielen läuft.

Und das mit UCS4 jetzt noch nicht so viel los ist, hatte ich mir schon gedacht.
Der Unicode Standard v4.0.0, mit dem die 4-Byte Unicodezeichen eingeführt wurden, ist glaube ich auch erst dieses Jahr offiziell rausgekommen.
Da aber die von Microsoft ja sonst alles einbauen, egal ob es richtig funktioniert oder nicht, hätte da also auch schon etwas vorhanden sein können.


Question Gibt es noch 'ne Möglichkeit an diesen Artikel ran zu kommen. Werd' mich zwar mal etwas umschauen. Hab aber keine großen Hoffnungen.
grüß dich, himitsu!

ich schreib n programm, wo ich auch osteuropäische und asiatische schriftzeichen verwenden können muss. ich benutze dafür die tnt-tools. das problem ist, wenn ich beispielsweise eine zeichenkette mit russischen zeichen habe (innerhalb einer tnt-komponente) und möchte die in eine datei schreiben, dann kann ich das nicht einfach über den normalen typ string machen - das hab ich inzwischen mitbekommen. offensichtlich muss ich dabei also mit widestring arbeiten. es geht nur irgendwie nicht, eine file of record zu machen, wobei im record nun nicht mehr der typ string ist, sondern widestring?

Delphi-Quellcode:
type Vocable = record
      Vlinks,Vrechts: widestring;
end;

var
  Form1: TForm1;
  Datei: file of Vocable;
naja ok. aber wenn man sich theoretisch einen font selbst macht, wo an den entsprechenden positionen einfach ein anderes zeichen gemalt ist, dann würde das ganz ohne tnt machbar sein. woher bekommt man denn derartig manipulierte fonts? ich bräuchte russisch, türkisch, italienisch, französisch, usw. (möglichst viel).

kannst du mir vielleicht helfen?

danke für deine aufmerksamkeit!

viva los tioz!


PAX
Erstmal zu den Fonts ... theoretisch könnte man die sich selber machen (hatte ich auch mal, weil ich 'ne andere Schrift und noch'n paar spezielle Zeichen brauchte), oder man sucht mal im INet ... irgendwo schwirren ja die gewünschten Fonts meistens auch schon fertig rum,
aber soooo optimal ist das dann ja auch nicht, da du dann ja jedesmal auf den nötigen Font umstellen und diese Information (welcher Font benötigt wird) auch noch irgendwie mit speichern mußt.

Am Einfachsten ist es also, wenn du bei Unicode bleibst (da ist ja schon alles vorhanden, bzw. wer's braucht, weiß wo/wie er/sie sich die nötigen Fonst installieren muß).


Nun gibt's aber auch mehrere Varianten, wie du nun den String speicherst.
Leider gibt's aber keine "gute" Möglichkeit die Standard-Textdatei-Funktionen so zu ändern, daß diese WideString-tauglich werden, also so wie ich es z.B. in 64-Bit für TextFile / File of xxx gemacht hatte, damit diese Funktionen 64-Bit-tauglich (also für Dateien größer 2 GB) sind.

Die Idee mit dem Record ist leider total falsch gewählt, denn Ansi-/WideStrings sind sozusagen dynamische Array's und so wie bei diesen dynamischen Arrays ist die Variable in Wirklichkeit nur ein Pointer aud den entsprechende Datenbereich. (OK, aus irgendwelchen gründen ist das beim WideString nicht ganz die Wahrheit, da dort Borland, warum auch immer einen OLE-String mißbraucht, aber das ist hierfür mal ein bissl unwichtig)

Also speicherst du mit dem Record nur die Pointer, welche nach dem Laden dann auf irgendwas, aber nicht unbedingt auf deine gewünschten WideStrings zeigen.


Die Typen-Defs für nachfolgendes:
Delphi-Quellcode:
Var F: File/File of Byte/oder ähnliches;
  T: TextFile;
  L: LongInt/Integer;
  W: WideString;
  C: WideChar;
  S: AnsiString;
Ansonsten ist nachfolgend immer ein schematischer Code zum Speichern und danach zum Aulesen angegeben und die Sachen zum öffnen/schließen der Dateien sind auch einfach mal weggelassen worden


Wenn nur ein einziger String in der Datei rumliegt:
Delphi-Quellcode:
Write(F, @W[1], Length(W) * 2);

SetLength(W, FileSize div 2);
Read(F, @W[1], Length(W) * 2);
Mit Längenangabe:
Delphi-Quellcode:
L := Length(W);
Write(F, @L, 4);
Write(F, @W[1], L * 2);

Read(F, @L, 4);
SetLength(W, L);
Read(F, @W[1], L * 2);
Mit abschließender #0 (also PWideChar):
Delphi-Quellcode:
Write(F, @W[1], L * 2 + 2);

// irgendwie bis zur nächsten #0 einlesen
// z.B.
W := '';
While not EoF(F);
  Read(F, @C, 2);
  If C = #0 Then Break;
  L := Length(W) + 1;
  SetLength(W, L);
  @W[L] := C;
End;

Das Write/WriteLn/Read/ReadLn für TextFile nimmt zwar auch WideStrings an, allerdings wird das intern nur in ANSI umgewandelt und auch als AnsiString gelesen/geschrieben.

Es ist allerdings auch möglich den WideString in ein ANSI-verträgliches Format umzuwandeln ... z.B. UTF8 und dieses dann als ANSI zu speichern (ohne einen Informationsverlust, wie bei der einfachen Umwandlung von Wide nach Ansi).
Delphi-Quellcode:
WideToUTF8(W, A);
WriteLn(T, A);

ReadLn(T, A);
UTF8ToWide(A, W);
Im Endefekt wird das mit dem Umweg über UTF8 erstmal am Praktischsten sein.


Ansonsten bastele ich (wenn ich mal wieder Zeit dafür hab) an meiner eigenen Dateiklasse weiter (diese kann bis jetzt AnsiString und WideString (BigEndian), wird aber noch um WideString (LE), sowie LongString (LE+BE) und eine bessere Verbindung zwischen diesen Typen erweitert)

[OT] Was ich jedem empfehlen kann ... Konsolen-, oder von mir aus auch NonVCL-Anwendungen mit Notepad erstellen und sich dann bei Gelegenheit mal überraschen zu lassen, was der Compiler zu dem File sagt ... macht echt Spaß
$2B or not $2B
  Mit Zitat antworten Zitat