Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Wie kann man TEncoding vergleichen? (https://www.delphipraxis.net/193688-wie-kann-man-tencoding-vergleichen.html)

Codehunter 29. Aug 2017 14:02

Wie kann man TEncoding vergleichen?
 
Moin!

Ich steh grad irgendwie auf dem Schlauch:
Delphi-Quellcode:
function EncodingToStr(const AEncoding: TEncoding): string;
begin
  if AEncoding is TEncoding.ANSI then // <-- Operator ist auf diesen Operandentyp nicht anwendbar
    Result:= 'ANSI'
  else if AEncoding is TEncoding.ASCII then // <-- Dito
    Result:= 'ASCII'
  else if AEncoding is TEncoding.UTF7 then // <-- Dito
    Result:= 'UTF7'
  else if AEncoding is TEncoding.UTF8 then // <-- Dito
    Result:= 'UTF8'
  else if AEncoding is TEncoding.Unicode then // <-- Dito
    Result:= 'Unicode'
  else
    Result:= 'ASCII';
Mit einfachem "="-Vergleich kompiliert das zwar, bringt aber immer False weil TEncoding.GetXYZ immer eine neue Instanz von TEncoding erzeugt. Mit InheritsFrom gehts auch nicht, weil z.B. ANSI und ASCII beide ein TMBCSEncoding sind. Nu sind mir irgendwie die Ideen ausgegangen.

TiGü 29. Aug 2017 14:11

AW: Wie kann man TEncoding vergleichen?
 
Delphi-Quellcode:
function EncodingToStr(const AEncoding: TEncoding): string;
begin
  Result := '';
  if AEncoding is TUTF7Encoding then // <-- easy
    Result := 'UTF7'
  else if AEncoding is TUTF8Encoding then // <-- easy
    Result := 'UTF8'
  else if AEncoding is TUnicodeEncoding then // <-- easy
    Result := 'Unicode'
  else if AEncoding is TMBCSEncoding then // <-- schwieriger, musste noch die CodePage auswerten
  begin
    if AEncoding.CodePage = Winapi.Windows.GetACP then
      Result := 'ANSI'
    else
      Result := 'ASCII';
  end;
end;

mkinzler 29. Aug 2017 14:14

AW: Wie kann man TEncoding vergleichen?
 
Man könnte es über TEncoding.EncodingName ( Codepage) versuchen.

TiGü 29. Aug 2017 14:16

AW: Wie kann man TEncoding vergleichen?
 
Korrektur (da man bissel aufpassen muss mit der Vererbung) und gleich mit Konsolentestprogramm:

Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  Winapi.Windows;

var
  I: Integer;

function EncodingToStr(const AEncoding: TEncoding): string;
begin
  Result := '';
  if AEncoding is TUTF8Encoding then // <-- easy
    Result := 'UTF8'
  else if AEncoding is TUTF7Encoding then // <-- easy
    Result := 'UTF7'
  else if AEncoding is TBigEndianUnicodeEncoding then
    Result := 'BigEndianUnicode'
  else if AEncoding is TUnicodeEncoding then // <-- easy
    Result := 'Unicode'
  else if AEncoding is TMBCSEncoding then // <-- schwieriger, musste noch die CodePage auswerten
  begin
    if AEncoding.CodePage = Winapi.Windows.GetACP then
      Result := 'ANSI'
    else
      Result := 'ASCII';
  end;
end;

begin
  try
    Writeln(EncodingToStr(TEncoding.ANSI));
    Writeln(EncodingToStr(TEncoding.ASCII));
    Writeln(EncodingToStr(TEncoding.BigEndianUnicode));
    Writeln(EncodingToStr(TEncoding.Default));
    Writeln(EncodingToStr(TEncoding.Unicode));
    Writeln(EncodingToStr(TEncoding.UTF7));
    Writeln(EncodingToStr(TEncoding.UTF8));

    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

TiGü 29. Aug 2017 14:19

AW: Wie kann man TEncoding vergleichen?
 
Zitat:

Zitat von mkinzler (Beitrag 1379842)
Man könnte es über TEncoding.EncodingName ( Codepage) versuchen.

Auch nicht verkehrt, je nachdem was man möchte:

Delphi-Quellcode:
    Writeln(TEncoding.ANSI.EncodingName);
    Writeln(TEncoding.ASCII.EncodingName);
    Writeln(TEncoding.BigEndianUnicode.EncodingName);
    Writeln(TEncoding.Default.EncodingName);
    Writeln(TEncoding.Unicode.EncodingName);
    Writeln(TEncoding.UTF7.EncodingName);
    Writeln(TEncoding.UTF8.EncodingName);
ergibt:

Code:
1252  (ANSI - Lateinisch I)
20127 (US-ASCII)
1201  (Unicode - Big-Endian)
1252  (ANSI - Lateinisch I)
1200  (Unicode)
65000 (UTF-7)
65001 (UTF-8)

Zacherl 29. Aug 2017 14:58

AW: Wie kann man TEncoding vergleichen?
 
Besser nicht über die Namen. Die scheinen ja lokalisiert zu sein.

Codehunter 29. Aug 2017 15:04

AW: Wie kann man TEncoding vergleichen?
 
Danke euch soweit, die Vergleicherei funktioniert nun soweit. Allerdings habe ich Probleme damit, eine TStringlist, die als Unicode-String vorliegt, gezielt in ein ASCII-Format zu speichern
Delphi-Quellcode:
SL.SaveToFile('DerDateiname.txt', TEncoding.ASCII)
. Dabei gehen die Umlaute verschütt (ü>u, ß>?)

Die Hilfe warnt da ja ausdrücklich: Achtung: System.SysUtils.TEncoding.ASCII ist ein 7-Bit-ASCII-Zeichensatz und daher mit UnicodeString (der Standard-String-Typ in RAD Studio) nicht kompatibel. Mit einem 7-Bit-Zeichensatz schlägt die Umwandlung von char in widechar (d.h. Unicode) für alle erweiterten ASCII-Zeichen fehl.

Hintergrund ist, dass das Programm dass ich mit meiner gespeicherten Datei versorgen will, kein Unicode oder UTF-8 versteht. Dass sich auf die Weise keine Multibyte-Zeichen speichern lassen ist ja klar, aber die Zeichen aus dem erweiterten ASCII-Zeichensatz (127-255) sollten doch machbar sein.

Ja nu, wieder so ein Fallstrick...

Uwe Raabe 29. Aug 2017 15:13

AW: Wie kann man TEncoding vergleichen?
 
Dann nimm doch TEncoding.ANSI!

Codehunter 30. Aug 2017 07:47

AW: Wie kann man TEncoding vergleichen?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1379858)
Dann nimm doch TEncoding.ANSI!

Das ist ja ein Ding! Ich bin gar nicht auf die Idee gekommen, ANSI überhaupt zu testen wenn 7-Bit-ASCII schon nicht geht.

Kurz erklärt warum ich hier Probleme habe: Ich lese eine INI-Datei die als UTF8 ohne BOM gespeichert ist, mit TIniFile ein. Da dieses über die API-Funktionen nur ANSI einliest, wandle ich alles mit DecodeUTF8 um. Anschließend sollen die gelesenen Werte in einer konfigurierbaren (!!!) Kodierung wieder geschrieben werden, in eine andere Datei.

Also lese ich da nun den Teststring "äöüßÄÖÜ" aus meiner Quell-INI ein, wandle mit DecodeUTF8 um, baue in einer TStringList die neue Datei zusammen und speichere die dann mit
Delphi-Quellcode:
TStringList.SaveToFile('Dateiname.txt', TEncoding.ANSI {.ASCII, .UTF8 oder .Unicode, je nach Benutzereinstellung})
. Der Teststring "äöüßÄÖÜ" liegt nach dem Einlesen tatsächlich noch korrekt als WideString im Speicher. Die fehlerhafte Umkodierung passiert dann beim Speichern aus TStringList:
Code:
Input-UTF8:    äöüßÄÖÜ
Widestring:    äöüßÄÖÜ
Output-ANSI:   äöüßÄÖÜ
Output-ASCII:  aou?AOU
Output-UTF7:   +AOQA9gD8AN8AxADWANw-
Output-UTF8:   äöüßÄÖÜ
Output-Unicode: äöüßÄÖÜ
Hinterher ausgelesen dann jeweils mit Notepad++. Für was ist das ASCII-Encoding dann eigentlich nütze?

Uwe Raabe 30. Aug 2017 07:52

AW: Wie kann man TEncoding vergleichen?
 
Zitat:

Zitat von Codehunter (Beitrag 1379919)
Kurz erklärt warum ich hier Probleme habe: Ich lese eine INI-Datei die als UTF8 ohne BOM gespeichert ist, mit TIniFile ein. Da dieses über die API-Funktionen nur ANSI einliest, wandle ich alles mit DecodeUTF8 um. Anschließend sollen die gelesenen Werte in einer konfigurierbaren (!!!) Kodierung wieder geschrieben werden, in eine andere Datei.

Warum dann nicht gleich so?
Delphi-Quellcode:
myIniFile := TMemIniFile(AFileName, TEncoding.UTF8); // kommt auch mit Dateien ohne BOM zurecht


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:11 Uhr.
Seite 1 von 2  1 2      

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