Problem mit Multibyte-Zeichen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Problem mit Multibyte-Zeichen

Beitrag von Dee »

Hallöchen sehr geehrte Lazarus-Community,

ich versuche schon seit einigen Tagen Zeichen mit mehr als einem Byte in einen Char zu speichern. Da Char nur 1 Byte hat, habe ich es mit WideChar probiert, welches ja 2 Byte hat. Leider klappt auch das nicht. Ich habe mich mit der ganzen Codierung mal auseinander gesetzt, doch gebracht hat es nichts.

Folgende Zuweisung wurde schon oft geschrieben, aber nie konnte ich eine Lösung dafür finden:

Code: Alles auswählen

 
var
  c: Char;
begin
  c := 'ä'; // Fehler, weil ä als String behandelt wird
end;
Dieses Beispiel zeigt auch nicht das gewünschte an:

Code: Alles auswählen

 
var
  c: Char;
  s: String;
begin
  s := 'ä';
  c := s[1];
  ShowMessage(c); // Gibt leere Meldung aus
end;
Damit klappt es, hilft mir aber nicht, da damit kein Char zurückgegeben wird:

Code: Alles auswählen

 
var
  s1, s2: String;
begin
  s1 := 'ä';
  s2 := s1[1] + s1[2];
  ShowMessage(s2); // Gibt ä aus
end;
Wenn eine Funktion ein Char als Parameter erwartet, kann kein Multibyte-Zeichen übergeben werden. Es sind nur ASCII-Zeichen möglich, aber keine ANSI-Zeichen, jedenfalls keine > 128. VkKeyScan (aus Windows-Unit: http://msdn.microsoft.com/en-us/library ... 85%29.aspx) benötigt als Parameter einen Char. Aus einem String durch Indexierung der einzelnen Zeichen ist es nicht möglich, Multibyte-Zeichen auszulesen (siehe oben). Ich habe auch schon von der Unit LazUTF8 gehört und auch Funktionen, wie UTF8Copy oder UTF8Length genutzt, nur bringen die mir nichts. Gibt es denn irgendeine Möglichkeit? Ich bin über jede Hilfe dankbar!

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Problem mit Multibyte-Zeichen

Beitrag von Michl »

Dee hat geschrieben:VkKeyScan (aus Windows-Unit: http://msdn.microsoft.com/en-us/library ... 85%29.aspx) benötigt als Parameter einen Char.
Was hast Du denn vor?!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Problem mit Multibyte-Zeichen

Beitrag von Mathias »

Guck dir dies mal an, da wird über WideChar diskutiert.

http://www.lazarusforum.de/viewtopic.php?f=10&t=2027
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Problem mit Multibyte-Zeichen

Beitrag von Dee »

Michl hat geschrieben:
Dee hat geschrieben:VkKeyScan (aus Windows-Unit: http://msdn.microsoft.com/en-us/library ... 85%29.aspx) benötigt als Parameter einen Char.
Was hast Du denn vor?!
Ich habe einen Passwort-Generator entwickelt, mit dem es möglich sein soll, dass generierte Passwort durch einen Tastendruck in ein Eingabefeld durch virtuelle Tastenhiebe eingibt. Erst habe ich es in Lazarus entwickelt. Dann habe ich gemerkt, dass es nicht alle Zeichen ausgibt. Letztendlich bin ich auch Delphi zurückgekommen und habe es dort umgesetzt und dort klappt es ohne Probleme.
Mathias hat geschrieben:Guck dir dies mal an, da wird über WideChar diskutiert.

http://www.lazarusforum.de/viewtopic.php?f=10&t=2027
Das habe ich mir auch schon durchgelesen, aber dort kommt es auch zu keinem Ergebnis, das mir helfen würde. Mir helfen keine Diskussionen. Ich will eine Lösung haben, nur finde ich sie nicht. Gibt es denn keine Funktion, die Multibytezeichen aus einem String zurückgibt?

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Problem mit Multibyte-Zeichen

Beitrag von theo »

Dee hat geschrieben: Gibt es denn keine Funktion, die Multibytezeichen aus einem String zurückgibt?
Doch, klar geht das. Mit Unicode muss man sich halt kurz befassen, bevor man es kapiert.

Es geht z.B. so:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var WS:WideString;
  i:integer;
begin
  WS:=UTF8Decode('abcöäüz');
  For i:=1 to length(WS) do ShowMessage(UTF8Encode(WS[i]));
end;  
oder so:

Code: Alles auswählen

uses LazUTF8;
 
..........
 
procedure TForm1.Button1Click(Sender: TObject);
var S:String;
  i:integer;
begin
  S:='abcöäüz';
  For i:=1 to UTF8Length(S) do ShowMessage(UTF8Copy(S,i,1));
end;   

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Problem mit Multibyte-Zeichen

Beitrag von Dee »

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var WS:WideString;
  i:integer;
begin
  WS:=UTF8Decode('abcöäüz');
  For i:=1 to length(WS) do ShowMessage(UTF8Encode(WideString(WS[i])));   // Typ-Cast fehlte
end; 
Man muss den Char noch casten, damit die Funtion weiß, mit welchem Typ sie arbeiten muss. Vielen Dank, für deine Antwort. Ich habe einfach nicht durchgesehen, was es mit den ganzen Funktionen auf sich hatte. Es ist das erste Mal, dass ich solche Probleme damit hatte. Jetzt bin ich schlauer. Danke! :)

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Problem mit Multibyte-Zeichen

Beitrag von theo »

Dee hat geschrieben: Man muss den Char noch casten, damit die Funtion weiß, mit welchem Typ sie arbeiten muss.
Wieso? Ich muss das nicht. Welche Lazarus Version hast du?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Problem mit Multibyte-Zeichen

Beitrag von mse »

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var WS:WideString; //oder UnicodeString für bessere performance auf Windows
 
Es bietet sich natürlich auch an mit einer Entwicklungsumgebung zu arbeiten, welche grundsätzlich UnicodeString benutzt wie z.B. Delphi oder MSEgui. WideStrings auf Windows sind OLE-strings welche einen höheren Overhead haben.
@theo:
Du arbeitest vermutlich auf Linux. In Linux gilt WideString = UnicodeString.

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Problem mit Multibyte-Zeichen

Beitrag von theo »

mse hat geschrieben: Du arbeitest vermutlich auf Linux. In Linux gilt WideString = UnicodeString.
Ich mag den Begriff "UnicodeString" nicht. FPC "UnicodeString" ist ein Referenzgezählter UTF-16 String, weiter nichts.
WideStrings sind älter, auch in Delphi. Das bisschen "Performance" interessiert hier erstmal nicht.

Aber schön, dass du wieder mal Werbung für andere Produkte einfliessen lassen konntest.
Bitte lass das, es ist nicht zielführend für Lazarus User in einem Lazarus Forum.
Besprich solche Dinge bitte in deinem eigenen Forum.
Danke.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Problem mit Multibyte-Zeichen

Beitrag von mse »

Und weil du den Begriff "UnicodeString" nicht magst führst du die armen weniger bewanderten Windows Benutzer aufs Glatteis? Siehe z.B. das type cast Problem von Dee.
Für alle Windows Benutzer: Bitte verwendet nicht "Widestring" sondern "UnicodeString" und "UnicodeChar".
WideString sollte ausschliesslich für den Datenaustausch mit externe COM-Objekten verwendet werden. Auf Linux spielt es keine Rolle da dort WideString = UnicodeString. Vernünftigerweise schreibt man auch dort im Sinne einer vielleicht mal notwendigen Portierung auf Windows "UnicodeString" statt "WideString", auch wenn dies theo nicht gefällt. ;-)

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Problem mit Multibyte-Zeichen

Beitrag von theo »

mse hat geschrieben:Und weil du den Begriff "UnicodeString" nicht magst führst du die armen weniger bewanderten Windows Benutzer aufs Glatteis? Siehe z.B. das type cast Problem von Dee.
Naja "Glatteis" ist ein bisschen dicke. Aber gut, du magst es nicht, wenn man deine Werbeaktionen kritisiert, deshalb grantelst du jetzt rum. :wink:

Das type Cast Problem von Dee kann ich nicht reproduzieren.
Habe es auf Lazarus 1.3 r46073M FPC 2.7.1 x86_64-linux-gtk 2 nach Win64 crosscompiled und der Compiler war happy.
Wieso sollte das auf "echtem" Windows anders sein?

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Problem mit Multibyte-Zeichen

Beitrag von Dee »

theo hat geschrieben:
Dee hat geschrieben: Man muss den Char noch casten, damit die Funtion weiß, mit welchem Typ sie arbeiten muss.
Wieso? Ich muss das nicht. Welche Lazarus Version hast du?
Es stehen drei Typen zur Auswahl, welche als Parameter übergeben werden können. Deshalb muss ich casten.

Lazarus: 1.2.0
FPC: 2.6.2
x86_64-win64-win32/win64
OS: Win7 64-Bit

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Problem mit Multibyte-Zeichen

Beitrag von Michl »

Ja, u.a. dieses Verhalten hat sich von FPC 2.6.4 -> 2.7.1 verändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

BeniBela
Beiträge: 320
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Problem mit Multibyte-Zeichen

Beitrag von BeniBela »

WideString/UnicodeString sollte man so nie verwenden!

Dann denkt man, es würde funktionieren, aber sobald man einen komplizierten Text hat, klappt es nicht mehr:

http://pastebin.com/raw.php?i=6FZgDfnr



Theos UTF-8 Klasse kann das besser

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Problem mit Multibyte-Zeichen

Beitrag von theo »

BeniBela hat geschrieben: Theos UTF-8 Klasse kann das besser
Danke! Ist zwar eigentlich ein Advanced Record, aber egal. Den gibt's immer noch hier:
http://www.lazarusforum.de/viewtopic.ph ... 94&p=54025

Antworten