Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Char to AnsiChar (https://www.delphipraxis.net/146203-char-ansichar.html)

PMM 15. Jan 2010 14:33


Char to AnsiChar
 
Beim Umstellen auf Delphi 2009 stolpere ich über eine Stelle, an der mir eine Funktion aus einer alten LIB einen AnsiChar (8Bit) liefert, der nun mit einem neuen CHAR (16Bit) verglichen werden muss. Der Compiler weigert sich zurecht das zu tun. Da ich aber weiss, dass im NewCHAR auch nur ein Ansi-Character stehen wird, hab ich nun einfach;
Delphi-Quellcode:
 oldchar = AnsiChar(NewChar)
geschrieben und der Compiler ist erstmal zufrieden. Ist dieser Cast sicher oder gibt es was besseres/richtigeres?
Peter

himitsu 15. Jan 2010 14:52

Re: Char to AnsiChar
 
Zitat:

Zitat von PMM
geschrieben und der Compiler ist erstmal zufrieden. Ist dieser Cast sicher oder gibt es was besseres/richtigeres?

Das würde ich nicht machen, außer es handelt sich um ASCII-Zeichen (7 Bit), dann zwischen Ansi und Unicode ist nur der ASCII-Bereich zueinander kompatiben und der Rest hängt von der CodePage ab.

Wenn du weißt, daß die alte Lib nur Ansi liefert und auch nie eine Umstellung geplant ist,
warum arbeitest du dann im neuen Programm nicht direkt mit AnsiChar?


Wie genau sind deine zu vergleichenden Typen/Variablen definiert?

Delphi-Quellcode:
var C: AnsiChar;
  T, C2: WideChar;
begin
  C := 's';
  C2 := 'd';
  If (MultiByteToWideChar(DefaultUserCodePage, 0, @C, 1, @T, 1) = 1) and (T = C2) Then
    {gleich}

PMM 15. Jan 2010 15:02

Re: Char to AnsiChar
 
> warum arbeitest du dann im neuen Programm nicht direkt mit AnsiChar?
Weil im "neuen Programm" halt auch eine LIB werkelt die nun mal einen CHAR liefert. Zu schreiben ist nur der "Glue-Code" der beide verbindet. Am besten wäre natürlich eine
Delphi-Quellcode:
 Function CharToAnsiChar(NewChar: Char): AnsiChar;
die ein Exception auslöst, wenn das Char da nicht reinpasst. Wie könnte sowas aussehen?
Peter

mkinzler 15. Jan 2010 15:03

Re: Char to AnsiChar
 
Zudem müsste dann auch eine direkte Zuweisung funktionieren

himitsu 15. Jan 2010 15:13

Re: Char to AnsiChar
 
Zitat:

CharToAnsiChar
Oben mal ein AnsiCharToChar, welches sich auch in eine Funktion kapseln ließe.

Andersrum und mit Exception isses etwas scherer, aber möglich.
> "Ersatzzeichen" abfragen
> umwandeln
> prüfen ob Result dem Ersatzzeichen entsprichen, aber es nicht schon vorher diesem entsprach
> und wenn ja, dann Exception

PMM 15. Jan 2010 15:27

Re: Char to AnsiChar
 
@himitsu
> Wie genau sind deine zu vergleichenden Typen/Variablen definiert?
als CHAR bzw. ANSICHAR
Das MultiByteToWideChar mit AnsiChar umgehen kann, hätte ich vom Namen her nicht erwartet. Werde ich mir aber mal ansehen.

@mkinzer
> Zudem müsste dann auch eine direkte Zuweisung funktionieren
Nee AnsiChar := CHAR geht genausowenig wie CHAR := AnsiCHAR

himitsu 15. Jan 2010 15:36

Re: Char to AnsiChar
 
Zitat:

Zitat von PMM
Das MultiByteToWideChar mit AnsiChar umgehen kann, hätte ich vom Namen her nicht erwartet.

Es kommt eben auf die CodePage drauf an.

UTF-8 (CodePage = 65001) ist z.B. der bekannteste Multibyte-Zeichensatz, welcher in einen "ANSI"-String reinpaßt.

MultiByte heißt es deswegen, weil verschiedene der Codepages bestimmte Zeichen in mehreren Bytes speichern.

PMM 16. Jan 2010 16:11

Re: Char to AnsiChar
 
Also ich hab es je so gemacht:
Delphi-Quellcode:
Function IsSameChar(aAnsiChar: AnsiChar; aChar: Char): Boolean;
Var aStr: String;
begin
  aStr := aAnsiChar;
  Result := aStr=aChar;
end;
Die Umwandlung AnsiChar -> Char macht die Zuweisung (allerdings auf einen String) automatisch und das funktioniert auch für nicht ASCII-Zeichen. z.B. liefert das AnsiChar #$80 das Zeichen '€' ($20AC). Die Umkehrung Char -> AnsiChar hab ich nicht hinbekommen. Kein der Funktionen Utf8ToAnsi, UTF8EncodeToShortString oder UnicodeToUtf8 liefert für das Zeichen '€' den Wert $80 zurück.

himitsu 16. Jan 2010 16:29

Re: Char to AnsiChar
 
Der untere Teile eines AnsiChar ist fest und der Obere hängt von der jeweiligen CodePage ab.

#$00 bis #$7F = ASCII / fest
#$80 bis #$FF = CodePage-abhängig

PS: #$80 ist nur in der "deutschen" CodePage ein € ... die Russen brauchen kein € und haben deswegen diesen "erweiterten" Bereich mit anderen Zeichen belegt.

Zitat:

Zitat von PMM
Kein der Funktionen Utf8ToAnsi, UTF8EncodeToShortString oder UnicodeToUtf8 liefert für das Zeichen '€' den Wert $80 zurück.

Hab ich gesagt, daß dieses UTF-8 sein soll?

UTF-8 ist EINER von VIELEN MultiByte-Zeichenätzen

nimm mal WideCharToMultiByte, zusammen mit der "deutschen" CodePage.
(nix anderes macht Delphi intern bei der Zuweisung an den String)

PMM 16. Jan 2010 16:55

Re: Char to AnsiChar
 
Zitat:

Die Umkehrung Char -> AnsiChar hab ich nicht hinbekommen.
stimmt nicht ganz. Es funktioniert z.B. die "Holzhammermethode":
Delphi-Quellcode:
Function CharToAnsiChar(Const aChar: Char): AnsiChar;
Var I: Integer;
 aStr: String;
begin
  I := 1;
  repeat
    aStr := AnsiChar(I);
    inc(I);
  until (I > 255) or (aStr=aChar);
  if (aStr=aChar)
    then Result := AnsiChar(I-1)
    else raise EConvertError.CreateFmt('Could''nt convert %s to AnsiChar.',[aChar]);
end;
Vermutlich geht es auch mit WideCharToMultiByte (das ist auch das was die genannten UTF8 Konverter intern verwenden, soweit ich das gesehen habe) wenn man die geeignete Codepage usw. auswählt (muss ja zur Laufzeit nicht die deutsche sein...).

So hier noch eine WideCharToMultiByte Variante
Delphi-Quellcode:
Function CharToAnsiCharX(Const aChar: Char): AnsiChar;
Var aStr: String;
  aAnsiStr: AnsiString;
Begin
  aStr := aChar;
  aAnsiStr := ' ';
  If WideCharToMultiByte(CP_ACP,0,@aStr[1],-1,@aAnsiStr[1],2,nil,nil) > 0
    then begin
    if aAnsiStr[2] = #0
      then Result := aAnsiStr[1]
      else raise EConvertError.CreateFmt('Could''nt convert %s to AnsiChar.',[aChar]);
    end
    else EConvertError.Create('CharToAnsiCharX: WideCharToMultiByte failed');
end;


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