Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Utf8ToAnsi funktioniert nicht mit Umlauten (https://www.delphipraxis.net/182403-utf8toansi-funktioniert-nicht-mit-umlauten.html)

juergen 21. Okt 2014 20:56

Utf8ToAnsi funktioniert nicht mit Umlauten
 
Hallo zusammen,

ich habe eine globale Stringliste (g_sl_Dateinamen) in welcher ich in einer anderen Procedure Dateinamen von UTF-8 Dateien einlese.
Diese UTF-8 Dateien sollen als ANSÌI-Dateien gespeichert werden. Dazu nutze ich die Funktion Utf8ToAnsi().
Nach der Ausführung von Utf8ToAnsi() steht anstelle der Umlaute nur noch ein Fragezeichen in dem String.

Delphi-Quellcode:
...
    if g_sl_Dateinamen.Count > 0 then begin
      try
        for j := 0 to g_sl_Dateinamen.Count - 1 do begin
          sl_Output_as_ANSII_File.Clear;
          sl_Input_UTF_8_File.LoadFromFile(g_sl_Dateinamen.Strings[j], TEncoding.UTF8);
          for i := 0 to sl_Input_UTF_8_File.Count - 1 do begin
            ShowMessage(sl_Input_UTF_8_File.Strings[i]);    // hier werden die Umlaute noch korrekt angezeigt
            sl_Output_as_ANSII_File.Add(Utf8ToAnsi(sl_Input_UTF_8_File.Strings[i]));
            ShowMessage(sl_Output_as_ANSII_File.Strings[i]); // hier stehen nur noch Fragezeichen anstelle der Umlaute
          end;
          if g_sl_Dateinamen.Count > 1 then
              sl_Output_as_ANSII_File.SaveToFile(IncludeTrailingBackslash(gs_ANSI_Datei_Pfad) + ChangeFileExt(gs_ANSI_Datei_Name, '') + '_' + IntToStr(j + 1) +
              ExtractFileExt(gs_ANSI_Datei_Name), TEncoding.ASCII)
          else sl_Output_as_ANSII_File.SaveToFile(IncludeTrailingBackslash(gs_ANSI_Datei_Pfad) + gs_ANSI_Datei_Name, TEncoding.ASCII);
        end;
      finally
        sl_Input_UTF_8_File.Free;
        g_sl_Dateinamen.Free;
        sl_Output_as_ANSII_File.Free;
      end;
    end;
...

Ich verstehe nicht warum die Umwandlung von Umlauten hier nicht funktioniert.
Weiß hier jemand Rat und kann mir weiter helfen?

Vielen Dank schon mal vorab!

EgonHugeist 21. Okt 2014 21:38

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Soweit mir bekannt kann TEncoding.ASCII (ASCII 7Bit) keine umlaute darstellen.
Delphi jagt den ganzen Text durch A2U -> U2A routinen. Beim U2A (Unicode to Ansi(CP_X)) hast du ein DataLoss Problem und LocaleCharsFromUnicode ersetzt all nicht unterstützten WideChars mit einenm '?'-Zeichen.

Habe jetzt die TEncoding-Klasse nicht im Kopf, doch sollte da nicht auch irgendein Ansi/RawByteString(CP_WhatEver)-Typ vorhanden sein?

Sir Rufo 21. Okt 2014 21:39

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Wenn du die Daten eingelesen hast, dann sind die nicht mehr UTF8 kodiert in der StringList!
Delphi-Quellcode:
var
  sl : TStringList;
begin
  sl := TStringList.Create.
  sl.LoadFromFile( 'utf8.txt', TEncoding.UTF8 );
  sl.SaveToFile( 'ansi.txt', TEncoding.Default );
  sl.Free;
end;

EgonHugeist 21. Okt 2014 21:43

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
@Sir Rufo

sieht mir aber nicht nach seinem Problem aus. Er liest ja die Daten korrekt. Klar ist dann alles als Unicode in der TStringList hinterlegt, doch beim SaveToStream hapert's IMHO.

Edit:
Lorb's vergiß es, dein Edit war schneller...

Sir Rufo 21. Okt 2014 21:46

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Zitat:

Zitat von EgonHugeist (Beitrag 1276891)
@Sir Rufo

sieht mir aber nicht nach seinem Problem aus. Er liest ja die Daten korrekt. Klar ist dann alles als Unicode in der TStringList hinterlegt, doch beim SaveToStream hapert's IMHO.

Edit:
Lorb's vergiß es, dein Edit war schneller...

Genau das ist aber sein Problem
Delphi-Quellcode:
Utf8ToAnsi(sl_Input_UTF_8_File.Strings[i])
.
Da wird eine Unicode-Zeichenfolge als UTF8 interpretiert und als Ansi ausgegeben. Das geht halt in die Hose :)

EgonHugeist 21. Okt 2014 21:49

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Right! Man sollte wirklich alles lesen...

Sir Rufo 21. Okt 2014 21:52

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Zitat:

Zitat von EgonHugeist (Beitrag 1276895)
Right! Man sollte wirklich alles lesen...

Die relevanten Stellen reichen ;)

EgonHugeist 21. Okt 2014 21:54

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Code:
sl_Output_as_ANSII_File.SaveToFile(IncludeTrailingBackslash(gs_ANSI_Datei_Pfad) + gs_ANSI_Datei_Name, TEncoding.ASCII)
Produziert am Ende aber auch den gleichen Käse, oder lieg ich jetzt falsch?

juergen 21. Okt 2014 21:58

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
@all,
danke für die Antworten! :thumb:
Ich war einfach zwanghaft besessen eine UTF-8 Umwandlung vornehmen zu müssen.
Wenn ich es so mache wie Sir Rufo es vorgeschlagen hat dann funktioniert alles. :-)
Allerdings kennt mein Delphi noch kein TEncoding.ANSI, dafür machts aber TEncoding.Default, denn TEncoding.ASCII darf ich nicht nehmen.

Danke für den Denkanstoß, ich hatte angenommen dass in der Stringliste alles als UTF-8 gespeichert ist, dabei ist es Unicode.

Gute Nacht! :DP

Sir Rufo 21. Okt 2014 22:04

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Delphi-Referenz durchsuchenTEncoding.Default ist ja auch die gewünschte ANSI Codepage :stupid:
(Wer setzt denn solche
Delphi-Quellcode:
TEncoding.ANSI
Gerüchte in die Welt?)

juergen 21. Okt 2014 22:09

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Zitat:

Zitat von Sir Rufo (Beitrag 1276902)
[OH](Wer setzt denn solche
Delphi-Quellcode:
TEncoding.ANSI
Gerüchte in die Welt?)

:-D:-D:-D
Siehe dein Edit :oops:

Sir Rufo 21. Okt 2014 22:13

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Zitat:

Zitat von juergen (Beitrag 1276904)
Zitat:

Zitat von Sir Rufo (Beitrag 1276902)
[OH](Wer setzt denn solche
Delphi-Quellcode:
TEncoding.ANSI
Gerüchte in die Welt?)

:-D:-D:-D
Siehe dein Edit :oops:

Mist, aufgefallen :stupid:

Uwe Raabe 21. Okt 2014 23:26

AW: Utf8ToAnsi funktioniert nicht mit Umlauten
 
Zitat:

Zitat von Sir Rufo (Beitrag 1276894)
Genau das ist aber sein Problem
Delphi-Quellcode:
Utf8ToAnsi(sl_Input_UTF_8_File.Strings[i])
.
Da wird eine Unicode-Zeichenfolge als UTF8 interpretiert und als Ansi ausgegeben. Das geht halt in die Hose :)

Der Name der Funktion ist (aus Kompatibilitätsgründen) irreführend und es wird dort ein UnicodeString (= string) zurückgegeben und kein AnsiString. Es erfolgt auch keine Umwandlung in ANSI, sondern der Fehler tritt dadurch auf, daß als Parameter ein RawByteString in UTF8-Kodierung erwartet wird, aber eben Unicode ankommt. Deswegen muss man bei RawByteString aufpassen, daß der Inhalt auch passt.

Nur so nebenbei: Für die Umwandlung von UTF8 nach Ansi bedarf es eigentlich keiner speziellen Routine. Allein durch die richtige Deklaration der Variablen erledigt der Compiler bei simpler Zuweisung den Rest (mit entsprechender Warnung).

Delphi-Quellcode:
var
  S: string;
  A: UTF8String;
  B: AnsiString;
...
  S := 'Häufiges Hüpfen verödet unverhältnismäßig den Rasen';
  A := S;
  B := A;
  Assert(B = S, 'Falsche CodePage!');


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 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