Stringirrsinn - Unicode, UTF8, Widestring,....

Für Fragen von Einsteigern und Programmieranfängern...
Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von af0815 »

Mittlerweile VERLIERE ich im Dschungel zwischen Codepages, Widestring, UTF8, Nicht UTF8, vielleicht UTF16 oder doch CPxxx unter Windows doch nicht, sondern nur unter *nix sondern die Version hat, die noch nicht, die LCL kann, die FCL machts anders,...... DEN ÜBERBLICK.

Gibt es eine vernünftige Beschreibung was für die aktuellen stable Lazarus und FPC für die Stingverwaltung gilt. Und auch vielleicht ein paar Beispiele (mit Umlauten) wie man was macht. Ich habe mittlerweile zB. aktuell keine Ahnung, was ein einfacher Length Befehl mir für ein Ergebnis liefern wird. Das ist nicht befriedigend. Und so Artikel wie Better Unicode Support in Lazarus tragen maximal zu mehr Verwirrung bei.

Es geht mir nicht um eine Diskussion wie sinnvoll das Ganze ist, sondern wie ich in der Praxis die Strings in einem Programm verwende, auch wenn ich zB. unter Windows Zugriffe auf Systemfunktionen machen muß, bzw. auch die österreichische Sprache verwende.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von theo »

Habe mich da auch schön länger ausgeklinkt. Deshalb fange ich jede diesbezüglichen Antwort mit "Ich glaube" an. :wink:
S.a. hier viewtopic.php?p=82518
Was ally sagt, entnehme ich dem Link jetzt nicht direkt. Aber es kann schon sein.

Ist jetzt eigentlich ein stabiler Punkt in der FPC Unicode Geschichte erreicht?
Dann würde es sich evtl. lohnen, mal wieder zu versuchen den Überblick zu gewinnen.
Aber da fehlt noch einiges in der RTL, oder?

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von wp_xyz »

Hier meine Sicht der Dinge, obwohl ich nicht behaupten kann, dass ich mich auf festem Untergrund befinde:

- Lazarus verwendet UTF8.
- FPC 3.0 verwendet jetzt auch UTF8 (keine UTF8-Konvertierung zwischen RTL und Laz mehr nötig)
- Bei UTF8 ergibt "Length(AString)" die Anzahl der Bytes, "UTF8Length(AString)" die Anzahl der Zeichen, wie bisher.
- Konvertierung braucht man weiterhin für Strings aus externen Quellen, z.B. Dateien, Internet-Daten, direkte Betriebssystemaufrufe. Da muss man halt weiterhin wissen, wie diese Strings codiert sind, und die entsprechende Funktion aus LazUTF8 oder LConvEncoding aufrufen. Wie bisher.

Also eigentlich hat sich gar nicht so viel verändert...

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

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von theo »

Kann man mit den "normalen" File Funktionen jetzt auch Dateinamen außerhalb der Windows ANSI Codepage ansprechen? (D.h. wird da jetzt das xxxW API benutzt?)

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von mschnell »

af0815 hat geschrieben:Gibt es eine vernünftige Beschreibung was für die aktuellen stable Lazarus und FPC für die Stingverwaltung gilt.


Die kann es nicht geben,weil es einfach nicht vernünftig ist .

Kann man dem Lazarus/FPC Team nicht vorwerfen, weil es in Delphi nicht vernünftig implementiert/definiert ist. Und schon gar nicht portierbar (Delphi XE arbeitet immer mit 16 Bit Strings, Lazaruns unter Linux sinnvoller Weise nicht.

Zwar nicht vernünftig aber doch definiert beschrieben sein sollte die aktuelle Implementierung im Wiki.

-Michael

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

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von Michl »

mschnell hat geschrieben:Die kann es nicht geben,weil es einfach nicht vernünftig ist .

Kann man dem Lazarus/FPC Team nicht vorwerfen, weil es in Delphi nicht vernünftig implementiert/definiert ist. Und schon gar nicht portierbar (Delphi XE arbeitet immer mit 16 Bit Strings, Lazaruns unter Linux sinnvoller Weise nicht.

Zwar nicht vernünftig aber doch definiert beschrieben sein sollte die aktuelle Implementierung im Wiki.

-Michael
Es gibt ein paar Entwickler von Lazarus, die in der Mailinglist (in der du ja auch aktiv bist) regelmäßig und eindringlich darauf hinweisen, dass man Lazarus RC1 bzw. jetzt RC2 testen soll, um alle möglichen Schwierigkeiten mit den neuen Strings aus dem Weg räumen zu können. Unmut hilft da nicht weiter.

Mein Fazit nach ausführlichen Tests ist, dass zumindest unter Windows, die neue Implementierung überhaupt kein Problem darstellt.

Im Gegenteil. Als neues Feature kommt hinzu, dass es erstmals möglich ist, reale, saubere ACP-Programme zu schreiben. Diverse Bugs hatte ich gemeldet bzw. Fixes dafür bereitgestellt. Allerdings glaube ich, dass in der Praxis kaum jemand die Möglichkeit nutzen wird, Programme mit der Option -dDisableUTF8RTL zu erstellen. Die meisten User können somit diese Option als "nice to have" betrachten und sich nicht großartig damit weiter auseinandersetzen.

Wenn man diese Option nicht nutzt, bleibt erstmal unter Windows alles beim Alten. Hat man zuvor normal mit Strings hantiert, sind diese weiterhin in Lazarus wie zuvor komplett in UTF8 kodiert. Daher sehe ich der neuen Lazarusversion 1.6 mit FPC 3 recht gelassen entgegen.

theo hat geschrieben:Kann man mit den "normalen" File Funktionen jetzt auch Dateinamen außerhalb der Windows ANSI Codepage ansprechen?
Ja. Das einzigste mir noch bekannte Problem ist (dazu habe ich auch noch ein Bugreport offen), dass ein Projekt von Lazarus selber im Datei- oder Pfadnamen keine Zeichen enthalten darf, die außerhalb der ACP liegen (der Compiler kann noch kein Unicode).
Zuletzt geändert von Michl am Mo 18. Jan 2016, 23:04, insgesamt 1-mal geändert.

Code: Alles auswählen

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

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von wp_xyz »

theo hat geschrieben:Kann man mit den "normalen" File Funktionen jetzt auch Dateinamen außerhalb der Windows ANSI Codepage ansprechen? (D.h. wird da jetzt das xxxW API benutzt?)

Hier ein Test: Erzeuge eine Textdatei mit beliebigem Inhalt und nenne sie 'αβγ.txt' - das ist mit Sicherheit nicht auf unserer ANSI-Codepage. Folgender Code lädt sie problemlos, d.h. ohne weitere Konvertierungen, in ein Memo:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
const
  fn = 'αβγ.txt';
begin
  Memo1.Lines.LoadfromFile(fn);
end;
 

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von af0815 »

Gibt es eigentlich ein utf8char ? Wenn ichdurch einen string iteriere der utf8 ist, so brauche ich den doch für die Umlaute ?! Oder wie geht das jetzt?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von wp_xyz »

Einen speziellen Datentyp UTF8Char gibt es m.E. nicht, letztendlich wäre das ein String mit 1 Zeichen, aber unterschiedlich vielen Bytes.

Schau dir die Unit LazUTF8 an, da gibt es viele Funktionen in diese Richtung. Was du wahrscheinlich suchst, ist sowas, wie die Funktion

Code: Alles auswählen

function UTF8CharacterToUnicode(p: PChar; out CharLen: integer): Cardinal; 
die den Zahlenwert der zu dem Zeichen gehörenden Bytes zurückliefert. Mit Hilfe von CharLen kannst du dann zum nächsten Zeichen weiterlaufen.

Ich habe auch schon

Code: Alles auswählen

function UTF8Copy(const s: string; StartCharIndex, CharCount: PtrInt): string;
gesehen, wobei StartCharIndex am Beginn eines Codepoint liegen muss, und CharCount mit Hilfe von function UTF8CharacterLength(p: PChar): integer zu ermitteln ist.

Aber so nebenbei gefragt: Brauchst du einen UTF8-Char wirklich? Wenn du einen String zu durchlaufen hast, z.B. für einen HTML-Parser, dann sind die zu suchenden Zeichen im Bereich <128, und damit reichen "normale" Chars aus.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von af0815 »

Sorry wenn ich sage, das ganze wird langsam pervers.Ich bin mittlerweile in der Stringverwaltung ausgestiegen. Pascal ist eine klare Sprache, was daaber jetzt in den Libraries abgeht, ist abschreckend und ich muss für mich sagen - Hände weg, bis ein klare, für den normalen Programmierer, verständliche Version gibt. Ich sage es ungern, aber MSE hat da recht, das er sich von dem Chaos abgrenzt.

Da darf jetzt keiner mehr sagen C oder C++ ist kompliziert.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von Michl »

af0815 hat geschrieben:Sorry wenn ich sage, das ganze wird langsam pervers.Ich bin mittlerweile in der Stringverwaltung ausgestiegen. Pascal ist eine klare Sprache, was daaber jetzt in den Libraries abgeht, ist abschreckend und ich muss für mich sagen - Hände weg, bis ein klare, für den normalen Programmierer, verständliche Version gibt. Ich sage es ungern, aber MSE hat da recht, das er sich von dem Chaos abgrenzt.

Da darf jetzt keiner mehr sagen C oder C++ ist kompliziert.

Andreas
das sehe ich überhaupt nicht so. Ob UTF16 oder UTF8, bei Unicode können Zeichen verschieden lang sein. UTF16 ist nicht die eierlegende Wollmilchsau. Ich persönlich habe mit UTF8 meinen Frieden gemacht.

Wahrscheinlich läuft diese Diskussion wieder in die Richtung, wie sie schon mehr als ein Dutzend mal hier, in der Mailinglist oder im englischen Forum da war. Dabei ist es zur Zeit eigentlich gar nicht so kompliziert, wobei man sagen muss, dass auch FPC Richtung UTF16 (ist auch schon ansatzweise möglich) gehen will und der aktuelle Stand vermutlich nur eine Zwischenlösung für di3 nächsten paar Jahre darstellt.

Code: Alles auswählen

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

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

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von theo »

af0815 hat geschrieben:Gibt es eigentlich ein utf8char ? Wenn ichdurch einen string iteriere der utf8 ist, so brauche ich den doch für die Umlaute ?! Oder wie geht das jetzt?


Ja, der ist definiert in LCLType.

Code: Alles auswählen

type
TUTF8Char = String[7]; // UTF-8 character is at most 6 bytes plus a #0       

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von mschnell »

Michl hat geschrieben:Es gibt ein paar Entwickler von Lazarus, die in der Mailinglist (in der du ja auch aktiv bist) regelmäßig und eindringlich darauf hinweisen, dass man Lazarus RC1 bzw. jetzt RC2 testen soll, um alle möglichen Schwierigkeiten mit den neuen Strings aus dem Weg räumen zu können. Unmut hilft da nicht weiter.

Stimmt .

Es nützt aber nicht viel etwas zu testen ,das nicht wirklich funktionieren kann.

Als Grundlage für eine ordentliche Betriebssystem-Unabhängige (!!!) String-Verarbeitung muss das Programm ohne Änderung des Codes intern sowohl mit UTF-8 (Linux) als auch mit UTF-16 (Windows) arbeiten können. Der Typ TStrings muss also mit variabler Codierung definiert werden. Wie das gehen kann, habe Ich (nach Aufforderung in besagtem Forum) in einem Wiki-Beitrag (englisch) beschrieben. Auf eine Realisierung werden wir nicht hoffen können, weil sowohl der Compiler als auch die RTL und die LCL angepasst werden müssten und es mit XE zwar kompatibel,aber doch anders ist.

Ich glaube (hab's aber noch nicht getestet), dass man bei Lazarus/fpc durch setzen der passenden Optionen (anders als in Delphi XE ) die ganze Unicode-Geschichte abschalten kann. Dann muss man natürlich bei allen Text Ein- und Ausgaben händisch eingreifen um die Texte in die Codierung zu konvertieren mit der man im Programm arbeiten möchte.

Lästig und nicht jedermanns Sache, aber man weiß wenigstens, was da vorgeht .

-Michael
Zuletzt geändert von mschnell am Di 19. Jan 2016, 12:02, insgesamt 4-mal geändert.

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

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von theo »

wp_xyz hat geschrieben:Einen speziellen Datentyp UTF8Char gibt es m.E. nicht, letztendlich wäre das ein String mit 1 Zeichen, aber unterschiedlich vielen Bytes.

Schau dir die Unit LazUTF8 an, da gibt es viele Funktionen in diese Richtung. Was du wahrscheinlich suchst, ist sowas, wie die Funktion

Code: Alles auswählen

function UTF8CharacterToUnicode(p: PChar; out CharLen: integer): Cardinal; 
die den Zahlenwert der zu dem Zeichen gehörenden Bytes zurückliefert. Mit Hilfe von CharLen kannst du dann zum nächsten Zeichen weiterlaufen.

Ich habe auch schon

Code: Alles auswählen

function UTF8Copy(const s: string; StartCharIndex, CharCount: PtrInt): string;
gesehen, wobei StartCharIndex am Beginn eines Codepoint liegen muss, und CharCount mit Hilfe von function UTF8CharacterLength(p: PChar): integer zu ermitteln ist.

Aber so nebenbei gefragt: Brauchst du einen UTF8-Char wirklich? Wenn du einen String zu durchlaufen hast, z.B. für einen HTML-Parser, dann sind die zu suchenden Zeichen im Bereich <128, und damit reichen "normale" Chars aus.


Wenn das immer noch nicht einfacher geworden ist, empfehle ich nach wie vor in aller Bescheidenheit meinen TUniString: :wink:
viewtopic.php?f=29&t=5894&p=54025

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Stringirrsinn - Unicode, UTF8, Widestring,....

Beitrag von mschnell »

theo hat geschrieben:Wenn das immer noch nicht einfacher geworden ist, empfehle ich nach wie vor in aller Bescheidenheit meinen TUniString: :wink:


Genau so etwas meinte ich mit explizitem Unicode-Handling,wo man weiß was da tatsächlich passiert.

-Michael

Antworten