![]() |
Unicode in Textfiles...
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:
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 ![]() 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:
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 :mrgreen:
Var F: File/File of Byte/oder ähnliches;
T: TextFile; L: LongInt/Integer; W: WideString; C: WideChar; S: AnsiString; Wenn nur ein einziger String in der Datei rumliegt:
Delphi-Quellcode:
Mit Längenangabe:
Write(F, @W[1], Length(W) * 2);
SetLength(W, FileSize div 2); Read(F, @W[1], Length(W) * 2);
Delphi-Quellcode:
Mit abschließender #0 (also PWideChar):
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);
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:
Im Endefekt wird das mit dem Umweg über UTF8 erstmal am Praktischsten sein.
WideToUTF8(W, A);
WriteLn(T, A); ReadLn(T, A); UTF8ToWide(A, W); 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ß :roll: |
Re: Unicode in Textfiles...
danke himitsu, wirklich selbstlos von dir, dass du dir die zeit für mich genommen hast! :-D
das problem is, ich schreibe in eine datei vom typ record. also praktisch mit diesen parametern:
Delphi-Quellcode:
bei der variante mit der zeigerspielerei hab ich nicht verstanden, warum die länge mit 2 multipliziert werden muss. und des weiteren müssen mehrere widestrings darin gespeichert werden, quasi anfang und ende eines jeden strings müssen irgendwie klar sein. vielleicht könnte man immer grundsätzlich eine feste länge der zeichenkette schreiben und den rest ggf. mit leerzeichen auffüllen?
type Vocable = record
Vlinks,Vrechts: string[255]; end; bei der 2. möglichkeit hab ich mal geguckt und musste feststellen, dass ich die funktion widetoutf8 nicht habe. es gibt aber konvertierungsfunktionen zwischen ansi und utf8, und unicode (is das nich widestring?) und utf8. das hat aber nich hingehauen und bei unicodetoutf8 seh ich nicht durch. :? aber theoretisch sollte das funktionieren, wenn ich widetoansi anwende? also wenn ich kyrillische buchstaben in der tntkomponente habe und diese konvertiere, in datei speichere und sie wieder auslese und zurücklade in die komponente (vorher wieder ansitowide), dann steht dort exakt das selbe wie zuvor? dankeschön für deine hilfe! :) PAX |
Re: Unicode in Textfiles...
ich hab gerade keine befehlsliste zur hand, aber das dritte argument bei write is doch die anzahl der zu schreibenden zeichen, gell? warum muss hier mal 2 multipliziert werden?
|
Re: Unicode in Textfiles...
Zitat:
Bei WideString könnte man höchstens einen Array verwenden. (diese Variante hatte ich ja oben auch noch vergessen -.-'')
Delphi-Quellcode:
Und dort dann muß man dann nur die Strings rein-/rauskopieren :)
type Vocable = record
Vlinks, Vrechts: array[1..255] of WideChar; end; Ob der Compiler auch bei WindeStrings eine automatische Konvertierung vornimmt, weiß ich jetzt garnicht, also ob Nachfolgendes gleich möglich ist:
Delphi-Quellcode:
Wenn nicht, dann muß man es halt selber machen.
Var V: Vocable;
S: WideString; V.Vlinks := S; S := V.Vlinks; z.B. zum reinkopieren:
Delphi-Quellcode:
MemCopy(@V.Vlinks[1], S[1], Length(S) * 2 + 2);
// natürlich nur, wenn der String (nach der obrigen Definition von Vocable) nicht länger als 254 Zeichen ist Zitat:
Zitat:
Eigendlich steht Unicode ja für das Gesamte Zeichensystem, also für die 1-, 2- und 4-ByteZeichen, aber oftmals wird der Name halt nur für die 2-Byte-Zeichen/-Strings verwendet -.-'' Also UnicodeToUtf8 / Utf8ToUnicode sind die Richtigen, für meine obrigen Beispiele. Als Umsetzung wäre z.B. folgendes möglich: (Ich hoffe mal es funktioniert so, ansonsten muß sich mal hier wer zu Wort melden, der die Definitionen der Befehle kennt ... konnte auf die Schnelle nur die Parameterliste bekommen und hab mir den Rest vor mir bekannten Funktionen zusammengereimt)
Delphi-Quellcode:
WideToUTF8(W, A);
i := UnicodeToUtf8(nil, @W[1], MaxInt); SetLength(A, i); UnicodeToUtf8(@A[1], @W[1], i);
Delphi-Quellcode:
UTF8ToWide(A, W);
i := Utf8ToUnicode(nil, @A[1], MaxInt); SetLength(W, i); Utf8ToUnicode(@W[1], @A[1], i); Zitat:
Zitat:
Code:
Und die Multiplication mit 2 kommt dfaher, weil hier ja je Zeichen 2 Byte vorliegen, also
Operation(Datei-Handle/-Variable, Zeiger auf Speicherbereich, zu bearbeitente Bytes);
Byte = Zeichen * 2. Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:09 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 by Thomas Breitkreuz