Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Mal wieder Kodierungsprobleme. ANSI UTF8 UTF16 (https://www.delphipraxis.net/194418-mal-wieder-kodierungsprobleme-ansi-utf8-utf16.html)

LTE5 17. Nov 2017 20:43


Mal wieder Kodierungsprobleme. ANSI UTF8 UTF16
 
Erstellt wird eine Resource-Datei. Sie beinhaltet Textdokumente.
Ein paar davon sind UTF-8 ohne BOM und ein paar ANSI.

Lade ich die Resource nun mit den hier stehenden Fragmenten, dann kommt bei der UTF8-Datei das korrekte Ergebnis. Bei der ANSI-Datei kommt eine Fehlermeldung.

Muss ich jetzt alle UTF-8-Dateien nach ANSI kodieren, umgekehrt oder die Funktion anpassen? Ehrlich gesagt habe ich nicht mal eine Ahnung worin der Unterschied liegt.

Delphi-Quellcode:
 ResourceStream := TResourceStream.Create(Instance, ResourceName, RT_RCDATA);
 try
  sl := TStringList.Create;

  try
   sl.LoadFromStream(ResourceStream, TEncoding.UTF8);
   Result := sl.Text;
  finally
   sl.Free;
  end;

....

Redeemer 17. Nov 2017 21:01

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
Du musst je nach Datei das korrekte Encoding angeben. Wenn du ANSI-Dateien als UTF-8 lädst, macht Delphi überhaupt nichts, weil das Encoding von Emba so definiert und deklariert wurde.

LTE5 17. Nov 2017 21:02

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
Wie gehe ich das denn an, wenn ich das Encoding nicht kenne?

Ich habe gelesen, ANSI sei veraltet. Stimmt das? Man solle am besten direkt UTF8 nehmen.

Redeemer 17. Nov 2017 21:10

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
ANSI ist nicht standardisiert und wird von der Locale bestimmt. Während alle westlichen PCs in der Regel dieselbe Locale haben (CP1252), wird sich das Programm auf Rechnern in anderen Regionen anders verhalten.

Das Encoding einer Textdatei kann ohne BOM nicht sicher herausgefunden werden. Ein klassischer Witz unter Windows XP war, eine Textdatei im Windowseditor zu erstellen und "Bill hid the facts" reinzuschreiben. Dann passierten lustige Dinge.
Firefox verhält sich bei ANSI beispielsweise abhängig von der TLD völlig unterschiedlich, obwohl ANSI CP1252 eindeutig als Standardzeichensatz von HTML5 definiert ist.

Aber zurück zum Thema: Alle Dateien sollten als UTF-8 gespeichert werden. Das verbraucht zwar mehr Speicherplatz, ist aber nötigt, denn bei Delphi kannst du die zu verwendende Locale nicht ohne weiteres angeben. Du kannst nur ANSI angeben (TEncoding.Default), aber das ist wie gesagt nicht standardisiert.

LTE5 17. Nov 2017 21:14

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
Sollte man dementsprechend auch TMemIniFile.Create mit TEncoding.UTF8 aufrufen? Wenn die Datei schon existiert aber nicht im UTF8-Format, gibts eine schöne Fehlermeldung.

Und:

Memo LoadFromFile ... muss ich dort nun auch TEncoding.UTF8 angeben? Weil wenn die Datei zufälligerweise kein UTF8 ist, gibt es auch eine Fehlermeldung.

mensch72 17. Nov 2017 21:30

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
..."worin liegt der Unterschied"...

https://de.wikipedia.org/wiki/UTF-8

da steht viel Text, aber irgendwo in der Mitte steht, das "quasi" im UTF8 ByteArray nach einem HEX "11xxxxxx" stets mindestens ein weiteres Byte mit "10xxxxxx" folgen wird... und exakt das ist der Trick, wie man mit 98% Sicherheit sich selbst "ohne BOM" eine "IsUTF8" Funktion schreiben kann!
(Man geht davon aus, dass praktisch fast nie in Ansi-EU-Sprachen aufeinanderfolgend solche ZWEI Umlaute(>$80) verwendet, die zulällig mit diesen Bitmasken korrellieren. Die Leute die sich das ausgedacht haben, verwenden diese Bitmasken so definitiv nicht zufällig und waren sich des Erkennungsproblems ohne "BOM" sehr wohl bewußt)

- also lasse es weiter beim UTF8 auf eine Exeption ankommen und schalte damit dann auf deine "AnsiVariante" um, oder:
- programmiere dir selbst schnell eine Funktion, welche deinen Stream als BYTEbyBYTE durchgeht und bei einem HEX "11xxxxxx" nachschaut ob das nachfolgende Byte UNGLEICH "10xxxxxx"... wenn ja dann Break und Result=ANSI, sonst weiter bis zum Ende und dann Result=UTF8
- klar ist das nicht 100% eineindeutig, aber es hat sich in der Praxis so bewährt und wird von eingen so gemacht:)

LTE5 17. Nov 2017 21:33

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
Ist das hier auch annehmbar?

Delphi-Quellcode:
Memo1.Lines.LoadFromFile('file.txt');
Memo1.Text := UTF8ToString(Memo1.Text);
Das Problem mit der Ini-Datei besteht trotzdem noch. Wenn jemand auf die irrsinnige Idee kommt die Datei nach Ansi zu konvertieren, gibts natürlich ein Problem denn ich hab als Encoding UTF8 beim Create der Ini angegeben.

Und ob das hier eine Lösung ist weiß ich auch nicht
Delphi-Quellcode:
 try
  inherited Create(FileName, TEncoding.UTF8);
 except
  on E: EEncodingError do
   inherited Create(FileName);
 end;

mensch72 17. Nov 2017 21:45

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
Solange du nicht weißt, "was" es für Daten sind, vermeide in Delphi alles was mit Char oder String zu tun hat!
-> TBytes, TByteAarray oder ein TMemoryStream sind hier z.B. die passenden Speichertypen.

Dann kannst du es mit
Delphi-Quellcode:
try
  Memo1.Text := DecodeUTF8toString(MemoryStream);
except
  Memo1.Text := DecodeANSItoString(MemoryStream);
end;
oder
Delphi-Quellcode:
if IsUTF8(MemoryStream) then
  Memo1.Text := DecodeUTF8toString(MemoryStream)
else
  Memo1.Text := DecodeANSItoString(MemoryStream);
praktisch recht einfach realisieren.

LTE5 17. Nov 2017 21:48

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
Es sind immer Textdaten. Ganz normale Textdateien.

Dieses ganze Encoding-Zeugs macht mich ganz wirr.

Muss man das überhaupt angeben? Speziell bei Ini-Dateien ist es komisch. Speichere ich eine frische Ini-Datei mit einer Section wo äöü vorkommt, wird es als ANSI gespeichert.
Speichere ich ohne Umlaute, Speichert Delphi es als UTF8.

Gibt es hier keine goldene, einfache Regel die man befolgen kann?
Oder wäre es besser zu sagen "wenn jemand die ini-dateien unbedingt verändern muss > sein Pech wenn Fehler auftreten" ?

mensch72 17. Nov 2017 21:57

AW: Mal wieder Kodierungsprobleme. ANSI UTF8
 
..."Es sind immer Textdaten. Ganz normale Textdateien"...
=> ex gibt keine ganz normalen Textdaten, ausser den 127 ASCII Zeichen!!!

Delphi oder WinAPI jenach dem welche "Ini" Funktionen du benutzt machen da also entweder UTF16, oder ANSI.(Nur Lazerus verwendet selbst UTF8)

- also behandle IniFiles als ByteStream und lade sie in einen TMemmoryStream.
- prüfe ob es UTF8 ist, und mache dann passned daraus ein TMemoryIniFile, sonst eben das TMemoryIniFile per Ansi Daten
- beim Speichern identisch nur anders herum oder hart kodiert auf Ansi oder UTF8, je nachdem was du bevorzugst


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 Uhr.
Seite 1 von 4  1 23     Letzte »    

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