AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt
Thema durchsuchen
Ansicht
Themen-Optionen

UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

Ein Thema von sECuRE · begonnen am 5. Apr 2005 · letzter Beitrag vom 8. Apr 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von sECuRE
sECuRE

Registriert seit: 10. Apr 2003
Ort: Heidelberg
360 Beiträge
 
Delphi 7 Professional
 
#1

UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 5. Apr 2005, 15:14
Hi,

ich hab kürzlich die Funktion UTF8ToAnsi gefunden und wenn in dem String nur UTF8-Zeichen oder "standard" vorkommen, funktioniert alles. Kommen allerdings "normale" Sonderzeichen (ISO-Irgendwas-Zeichensatz), also äöüß vor, bricht die Funktion ab und hinterlässt einen leeren String - nicht grade schön. Ich hab deshalb die Funktion etwas umgeschrieben:
Delphi-Quellcode:
// Das Copyright dieser Funktion liegt bei Borland, ich hab lediglich 4 Zeilen an verschiedenen Stellen ergänzt. Die Funktion findet man in der System.pas wenn man eine Delphi-Version mit Sourcecode der VCL hat.
function _Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal; overload;
var
  i, count: Cardinal;
  c: Byte;
  wc: Cardinal;
begin
  if Source = nil then
  begin
    Result := 0;
    Exit;
  end;
  Result := Cardinal(-1);
  count := 0;
  i := 0;
  if Dest <> nil then
  begin
    while (i < SourceBytes) and (count < MaxDestChars) do
    begin
      wc := Cardinal(Source[i]);
      Inc(i);
      if (wc and $80) <> 0 then
      begin
        if i >= SourceBytes then begin
          dest[count]:=widechar(source[i-1]); // von mir eingefügt, normal stand hier "exit;"
          Inc(count);
          continue;
        end; // incomplete multibyte char
        wc := wc and $3F;
        if (wc and $20) <> 0 then
        begin
          c := Byte(Source[i]);
          Inc(i);
          if (c and $C0) <> $80 then begin
            dest[count]:=WideChar(source[i-2]); // von mir eingefügt, normal stand hier "exit;"
            Inc(count);
            Dec(i);
            continue;
          end; // malformed trail byte or out of range char
          if i >= SourceBytes then begin
            dest[count]:=WideChar(source[i-2]); // von mir eingefügt, normal stand hier "exit;"
            Inc(count);
            continue;
          end; // incomplete multibyte char
          wc := (wc shl 6) or (c and $3F);
        end;
        c := Byte(Source[i]);
        Inc(i);
        if (c and $C0) <> $80 then begin
        dest[count]:=widechar(source[i-2]); // von mir eingefügt, normal stand hier "exit;"
        Inc(count);
        Dec(i); continue; end; // malformed trail byte

        Dest[count] := WideChar((wc shl 6) or (c and $3F));
      end
      else
        Dest[count] := WideChar(wc);
      Inc(count);
    end;
    if count >= MaxDestChars then count := MaxDestChars-1;
    Dest[count] := #0;
  end
  else
  begin
    while (i < SourceBytes) do
    begin
      c := Byte(Source[i]);
      Inc(i);
      if (c and $80) <> 0 then
      begin
        if i >= SourceBytes then exit; // incomplete multibyte char
        c := c and $3F;
        if (c and $20) <> 0 then
        begin
          c := Byte(Source[i]);
          Inc(i);
          if (c and $C0) <> $80 then exit; // malformed trail byte or out of range char
          if i >= SourceBytes then exit; // incomplete multibyte char
        end;
        c := Byte(Source[i]);
        Inc(i);
        if (c and $C0) <> $80 then exit; // malformed trail byte
      end;
      Inc(count);
    end;
  end;
  Result := count+1;
end;
Nach verschiedenen AND/OR-Verknüpfungen wird also abgebrochen, diese Abbrüche hab ich einfach blind ersetzt und es funktioniert. Dass die Lösung nicht sehr schön ist, ist mir klar. Mit anderen Umlauten außer öäüß hab ich die Funktion bisher nicht getestet.

Meine Frage nun: Wozu sind die ganzen AND/OR-Verknüpfungen da, was wird da überprüft? Und: Wie kann man meine Lösung verbessern? Gibt es da schon Funktionen, mit denen man "gemischte" Strings vereinheitlichen kann?

BTW: (Zum testen) UTF8-"ö": ö

Vielen Dank & cu
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 14:36
Hab ich das jetzt richtig verstanden ???

Du hast einem UTF8-String direkt ein Sonderzeichen (z.B. das ö) untergeschoben und diesen "defekten" UTF8-String dann an UTF8toAnsi übergeben, worauf dieser Funktion dann natürlich abgestürtzt ist?

Delphi-Quellcode:
Var S: String;
  D: PWideChar;

S := 'ö';

Utf8ToUnicode(D, 1, PChar(S), 1);

Na kein Wunder, dass diese Funktion so reageirte ... schau dir lieber mal das Format eines UTF8-Strings an ... ein UTF8String ist kein AnsiString
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von sECuRE
sECuRE

Registriert seit: 10. Apr 2003
Ort: Heidelberg
360 Beiträge
 
Delphi 7 Professional
 
#3

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 15:23
Hi,

also ich hab's so gemacht:
Delphi-Quellcode:
function ConvertString(S:string):string;
begin
result:=UTF8ToAnsi(S);
end;

// ...
ConvertedString:=ConvertString('test'); // funktioniert
ConvertedString:=ConvertString('ö'); // funktioniert (UTF8)
ConvertedString:=ConvertString('test äöü'); // funktioniert NICHT :(
Daraufhin hab ich die Funktion wie oben "gepatcht". Das funktioniert dann.

Meintest du das so? Oder ist der Aufruf wie ich ihn gemacht hab doch richtig?

Danke & cu
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.197 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 15:31
Zitat von sECuRE:
Daraufhin hab ich die Funktion wie oben "gepatcht". Das funktioniert dann.

Meintest du das so? Oder ist der Aufruf wie ich ihn gemacht hab doch richtig?

Danke & cu
Ich würde ihn lieber so machen. UTF8ToAnsi sollte nur das machen für was es bestimmt ist und Nicht-UTF8 bzw. gemischte Strings wandeln. Entweder UTF8-String oder keiner.

Delphi-Quellcode:
function ConvertString(S:string):string;
begin
result:=UTF8ToAnsi(S); // Delphi-Orginal-Funktion
if result = 'then // String leer, wenn kein UTF8 -> Orginal Zurückliefern
  result := S;
end;
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 15:35
Genau das meinte ich und genau das ist der Fehler.

ÄÖÜ ist Ansi und nicht UTF8 ... also kannst du das nur andersrum machen AnsiToUTF8.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von sECuRE
sECuRE

Registriert seit: 10. Apr 2003
Ort: Heidelberg
360 Beiträge
 
Delphi 7 Professional
 
#6

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 15:56
Hi,

OK - wie überprüf ich denn nun, ob irgendwo Ansi im String vorkommt (bewusst auch Zeichen außer äöü) und wie verhalte ich mich in der Situation richtig, in der ich sowohl UTF8 als auch Ansi parsen will?

Danke & cu
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 16:16
Du mußt schon selber wissen, oder der String ein Ansi, UTF, oder sonst irgendein Stringformat hat und dementspechend mußt du dann auch die Funktionen auswählen


Bei Delphi ist ist z.B. der UTF8String indern auch nunr als eine Ableitung des AnsiStrings definiert, wodurch daher keine Programmseitige Unterscheidung möglich ist.

Ansi/Wide/UTF8/UTF16/UTF32.... das sind alles Stringformatierungsvarianten, dass heißt, das die alle die Zeichen in einem anderem Format speichern.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von sECuRE
sECuRE

Registriert seit: 10. Apr 2003
Ort: Heidelberg
360 Beiträge
 
Delphi 7 Professional
 
#8

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 16:36
Hi,

naja prinzipiell hab ich immer das selbe Stringformat. Ich les den Text von einem Indy-Clientsocket, gesendet wird der vom IRC-Server. Was der IRC-Client nun reinschreibt auf der Gegenseite bleibt ihm überlassen - meistens ANSI, im Falle von XChat halt standardmäßig UTF-8.

Die Zeichen werden also alle gleich gespeichert würd ich sagen, deshalb möcht ich ja die UTF8-Zeichen da "rauskonvertieren".

Danke & cu
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.197 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 16:42
Zitat von sECuRE:
naja prinzipiell hab ich immer das selbe Stringformat. Ich les den Text von einem Indy-Clientsocket, gesendet wird der vom IRC-Server. Was der IRC-Client nun reinschreibt auf der Gegenseite bleibt ihm überlassen - meistens ANSI, im Falle von XChat halt standardmäßig UTF-8.
Normalerweise wird bei Internet-Protokollen noch irgendwo die verwendet Codierung (z.B. UTF8) mitgeliefert.
D.h. dein Ansatz würde schon scheitern, wenn nicht UTF8 bzw. 1252-1 verwendet wird.
Da ich Indy nicht verwende weiß ich nicht wo du dort nachschauen mußt.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 7. Apr 2005, 17:08
Nachtrag:
Im Grundegenommen kannst du deine "umgebaute" Prozedur wegschmeißen ... da sie ja jetzt Fehlerhaft ist.


Aber wenn du nicht nachschauen kannst, was genau ankommen, also ob mal Ansi oder UTF ankommt, kannst du ja einen "nicht" so ganz guten Weg versuchen.

Wie gesagt, perfekt ist das nicht.
Es wird halt versucht den String von UTF8 nach Ansi umzuwandeln
und bei einem Fehler, also wenn der String kein UTF8-String ist, dann wird er als AnsiString verwendet.
Delphi-Quellcode:
SIn := ... // die empfangenen Daten

Try
  // von UTF8 nach ANSI umwandeln
  SOut := UTF8ToAnsi(SIn);
Except
  // und bei Fehler die Daten so übernehmen
  SOut := SIn;
End;

// SOut enthält jetzt (vermutlich) die Daten im ANSI-Format
Also versuche lieber rauszubekommtn was ankommt und dann dementsprechend diese Daten dann zu verwenden.
Delphi-Quellcode:
S := {empfangene Daten}
If {Datenformat der empfangenen Daten = UTF8} Then
  S := UTF8ToAnsi(S);

// Hier hätte man dann S im ANSI-Format (wenn nur ANSI und UTF8 möglich ist)
PS: in delphi wird standardmäßig das ANSI-Format verwendet,
weßhalb derzeit der String und der AnsiString genau das Selbe darstellen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:49 Uhr.
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