WideString, AnsiString, UTF8String, UCS4String Verwirrung

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von RSE »

Hallo!

Ich bin letztens umgestiegen auf Lazarus 0.9.26 und so langsam wird mir bewusst, dass mit UTF8 doch einige unerwartete Probleme Einzug gehalten haben. Um diese zu verstehen, möchte ich jetzt als erstes einmal Klarkeit über die ganzen Stringtypen erlangen. Ein bisschen Grundwissen habe ich ja schon durch diesen Beitrag erlangt: http://www.lazarusforum.de/viewtopic.php?f=10&t=2027" onclick="window.open(this.href);return false;

Als ich jetzt in den Sourcen mal zur Deklaration von UTF8Decode gesprungen bin, um zu sehen was es noch für ähnliche Funktionen gibt, hat mich die Verwirrung übermannt. Neben den mir bekannten String und ShortString gibt es dort WideString, AnsiString, UTF8String und UCS4String. Von einfach nur String keine Spur. Es wäre super, wenn jemand einmal Ordnung in alle Stringtypen (Übersichtshalber könnte man auch gleich PChar kurz ansprechen) bringt und mir die folgenden Fragen beantworten kann:

Welcher Stringtyp ist "String" jetzt eigentlich? Noch ein weiterer?
Was haben die einzelnen verschiedenen Stringtypen für eine Bedeutung, wozu braucht man sie? (insbes. WideString und UCS4String)
Wann habe ich es mit welchem Stringtyp zu tun? (z.B. eine String-Quelltextkonstante ist UTF8, da die Quelltextdatei ja jetzt UTF8 ist)
Was habe ich weiter zu beachten, wo gibt es versteckte Fußangeln? (Dass var a: string; a := 'ä'; showmessage(a[1]); so nicht mehr geht, ist klar)
Weitere Fragen entstehen bestimmt bei besserem Verständnis ;-)

Um gleich einer noob-Abstempelung vorzubeugen: Ich habe mit Google keine vergleichbare Übersicht, wie ich sie hier erbitte, gefunden. Um mir alles aus Einzelstücken zusammenzureimen, fehlt mir einfach der Überblick. Vielleicht gibt es ja einen, der einen Grundsatz-Leitartikel über dieses Thema verfassen kann, der wäre dann sicherlich für viele hilfreich. Falls es so etwas doch schon geben sollte, würde ich mich natürlich auch über einen Link freuen. Ansonsten kann auch jeder beitragen was er weiß, und ich erstelle dann eine Zusammenfassung, die ihr dann berichtigen dürft und die zum Schluss als Nachschlagewerk für alle Stringtypen herhalten kann.


MfG
RSE
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von RSE »

Mein bisheriges Wissen:

ShortString ist ein 256Byte langes (dynamisches?) Array[1..255] of Char. Jeder Char ist ein ANSI-Code. An Position 0 steht die Länge des Strings.

String (= LongString?) ist eine Struktur, die in der 32Bit-Welt maximal 2^32 Zeichen aufnehmen kann. An Position 0 steht hier der Zeiger auf das erste Zeichen?

PChar ist ein nullterminierter String, PChar selbst ist ein Zeiger auf einen Speicherbereich. In diesem Speicherbereich folgen ANSI-Zeichen (8Bit) aufeinander, das Zeichen #0 bildet den Abschluss.

1. ungeklärte Frage: was ist eigentlich mit "ANSI" gemeint? Eine soweit noch undefinierte Codepage für 8-Bit-Code?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von Euklid »

RSE, du sprichst mir gerade aus dem Herzen. Ich habe mittlerweile auch den Überblick verloren und wäre jedem dankbar, der hier mal eine tabellarische Übersicht schreiben könnte. Das könnten wir dann, wenn Monta einverstanden ist, in die WissensDB stellen.

Die gute alte Zeit, als String noch String war... ;)

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von RSE »

Genau so etwas schwebt mir vor :-D
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

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: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von mschnell »

RSE hat geschrieben:ShortString ist ein 256Byte langes (dynamisches?) Array[1..255] of Char. Jeder Char ist ein ANSI-Code. An Position 0 steht die Länge des Strings.
Struktur: Klar ! Codierung ANSI=??? ich vermute die verwendete Codepage hängt von der "lokale"-Einstellung ab. Wird in Linux auch ANSI-Codierung verwendet ? Bei einer ähnlichen "lokale" dieselbe oder eine andere Codepage wie bei Wndows ?
RSE hat geschrieben:String (= LongString?) ist eine Struktur, die in der 32Bit-Welt maximal 2^32 Zeichen aufnehmen kann. An Position 0 steht hier der Zeiger auf das erste Zeichen?
Ziemlich offensichtlich ist (defaultmäßig) String = Widestring. Struktur: die RTL stellt für Widestring anscheinend (wie bei ANSIString) eine Verwaltung zur Verfügung, die dem Programmierer eine Umgebung bietet, die es erlaubt, Strings wie Zahlen verwenden (und nicht klassisch wie Pointer-Verwaltete strukturen wie Objekte und danymische Arrays): "a:=b; b[1]:='x';" dann bleibt a[1] (anders als bei einem dynamischen Array) unverändert. Bei ANSIStrings (Windows und Linux) und Widestrings nur in Linux wird - wie hier letztens dargelegt - ein "lazy-copy" Algorithmus verwendet, bei Widestrings in Windows anscheinend nicht (alle Zeichen werden immer kopiert). Wenn ich das richtig sehe ist das in jedem Fall ohne "reference counting" nicht möglich.

Obwohl an ich an diversen Stellen anderes gelesen habe scheinen Widestrings (und WideChars) UCS2 kodiert zu sein (genau 16 Bit/Zeichen).
RSE hat geschrieben:PChar ist ein nullterminierter String, PChar selbst ist ein Zeiger auf einen Speicherbereich. In diesem Speicherbereich folgen ANSI-Zeichen (8Bit) aufeinander, das Zeichen #0 bildet den Abschluss.
in ANSIStrings sind die Zeichen genauso codiert (deshalb sind die typen sehr schön kompatibel: pchar(s) braucht sehr wenig overhead.) Nur kommt bei ANSIStrings die Verwaltung ("reference-counting" und "lazy copy") hinzu.
RSE hat geschrieben: ungeklärte Frage: was ist eigentlich mit "ANSI" gemeint? Eine soweit noch undefinierte Codepage für 8-Bit-Code?
Gilt für short strings und ANSIStrings (s.o.) in Turbo-Delphi definiert offensichtlich die in Windows eingestellte "lokale" die Kodierung (Uppercase funktioniert bei mir jedenfalls für deutsche Umlaute. Bei Lazarus klappte es in meinen ersten Versuchen nicht (siehe anderer Thread hier).

Weitere ungeklärte Frage: Der Quellcode scheint nun utf8-codiert zu sein (ASCII-code mit ca:100 sichtbaren Zeichen, bei erweiterten Codes kommen durch Sondercodes eingeleitete multibyte-Kodierungen zum Einsatz).

Unwichtige Frage: Kann man jetzt (wie in den neusten Delphi-Versionen) Variablen-Namen auch mit Umlauten und chinesischen Zeichen deklarieren ?
Wichtige Frage: wie wird eine String-Konstante in eine Variable geschrieben ? "Typisierte Konstante" vs "untypisierte Konstante" ? Macht der Compiler das automatisch "wie gewünscht" oder muss man "von Hand" eine konvertierung (utf8->xy) aufrufen ?

"Uppercase-Problem": siehe anderer Thread.

-Michael

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: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von mschnell »

Euklid hat geschrieben:RSE, du sprichst mir gerade aus dem Herzen. Ich habe mittlerweile auch den Überblick verloren und wäre jedem dankbar, der hier mal eine tabellarische Übersicht schreiben könnte. Das könnten wir dann, wenn Monta einverstanden ist, in die WissensDB stellen.
Vielleicht kann man da Anregungen finden ?: http://www.localisation.ie/resources/co ... aucius.pps" onclick="window.open(this.href);return false;
Euklid hat geschrieben:Die gute alte Zeit, als String noch String war... ;)
Einfach ANSIStrings verwenden :) Dann bleibt alles beim Alten. Ich vermute es gibt eine Compiler-Einstellung, die den Type "String" als ANSIString definiert statt als Widestring. Dann kannst Du die RTL und die LCL wohl auch so übersetzen.(Dank Open Source !!!) Für "internationale" Programme ist Widestring natürlich besser.

-Michael

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

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von theo »

Ich glaube man sollte jetzt nicht alles durcheinanderwerfen.

Zum Verständnis des Unicode Aspekts tragen Überlegungen zur Implementierung der Strings (Referenzgezählt, Null-Terminiert etc.) erstmal nur weitere Verwirrung bei.

Auch sollte man die grundlegenden Datentypen nicht mit Codierungen in einen Topf werfen.
Erstmal ist ein AnsiString ein "beliebig langer" String dessen Elemente (MyAnsiString[1]) 1 Char (Byte) lang sind (256 versch. Zeichen).
Ein WideString Element (MyWideString[1]) ist 2 Byte (1Word) lang, kann also grundsätzlich 65k versch. Zeichen halten.
Dann gibt es noch die alten ShortString die begrenzt lang sind und auch 1 Char Elemente haben.

Das ist erstmal alles Wichtige zu den Datentypen!!!

Die Codierung ist eine andere Sache:
Ein UTF8String ist für den Compiler auch nur ein AnsiString. Der Unterschied ist, dass er nicht auf eine Tabelle von 256 Zeichen mappt sondern alle Zeichen > #127 in Sequenzen, also mit mehr als einem Byte speichert. Das Problem bei UTF8 ist, dass es sowas wie einen UTF8Char Datentypen eigentlich nicht gibt. D.h. ein UTF-8 'a' ist ein Char, ein UTF-8 'ä' ist ein String!!

Ein WideString-Element (WideChar) kann von natur aus fast alle nötigen Zeichen "adressieren" (UCS-2) obwohl mit "surrogate pair handling" auch Zeichen über 65k dargestellt werden können (UTF 16).

Diese Tabellen zeigen eigentlich recht gut worum's geht ("Unicode Codepos." entspricht einem WideChar-Wert, "UTF-8" der Utf8 Sequenz):
http://www.utf8-zeichentabelle.de/unico ... tart=12592" onclick="window.open(this.href);return false;

BOM sind v.a. für's Streaming und zwischen untersch. Plattformen von Bedeutung. Kann man getrost erstmal vergessen, bis der Rest begriffen ist.

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: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von mse »

string
http://www.freepascal.org/docs-html/ref ... 330003.2.2
Typ zur Speicherung von Text, Implementierung von Compiler-Einstellungen abhängig.

shortstring
http://www.freepascal.org/docs-html/ref ... 340003.2.3
Ein Array von 256 Bytes, das erste Byte bezeichnet die Anzahl gültige Zeichen. Lokale shortstring Variablen belegen Speicher im Stack.

ansistring
http://www.freepascal.org/docs-html/ref ... 350003.2.4
Ein Speicher Block im Heap, Aufbau:

Code: Alles auswählen

 
  TAnsiRec = Packed Record
    Ref,
    Len   : SizeInt;
    First : Char;
  end;
 
Nach First folgen die weiteren 8-Bit Zeichen des String, nach dem letzen Zeichen folgt ein #0.
In einer ansistring Variable wird ein Pointer auf First gespeichert, ein leerer ansistring wird mittels NIL Pointer dargestellt. Bei der Zuweisung eines ansistring an eine ansistring Variable wird der Pointer kopiert und Ref inkrementiert, falls der Pointer nicht NIL ist. Es muss also nicht der gesamte Stringinhalt kopiert werden, was eine wesentlich besserer Leistung ermöglicht.
Verlässt eine ansistring Variable den Sichtbarkeitsbereich, wird Ref dekrementiert falls der Pointer nicht NIL ist. Erreicht Ref Null, wird der Speicherblock freigegeben. Dieser Mechanismus gilt auch für dynamische Arrays.
Wird auf ein Zeichen schreibend zugegriffen (ansistring1[1]:= 'A';), wird zuerst eine Kopie des Speicher Blocks erstellt, falls Ref >1 ist, damit sich die Änderung nicht auf andere "Besitzer" des ursprünglichen Strings auswirken. Dies gilt *nicht* für dynamische Arrays.

widestring
http://www.freepascal.org/docs-html/ref ... 360003.2.5

Unter Linux und anderen Unix-Systemen:
Ein Speicher Block im Heap, Aufbau:

Code: Alles auswählen

 
  TWideRec = Packed Record
    Ref : SizeInt;
    Len : SizeInt;
    First : WideChar;
  end;
 
Die einzelnen Zeichen sind 16Bit statt 8Bit breit, im Übrigen gilt das unter ansistring Gesagte.

Unter Windows:
Ein Speicher Block im Windows OLE-System Speicher, Aufbau:

Code: Alles auswählen

 
  TWideRec = Packed Record
    Len   : DWord;
    First : WideChar;
  end;
 
Hier wird keine Referenzzählung durchgeführt, Kopieroperationen kopieren den kompletten Speicherblock. Dadurch dass kein Heapspeicher verwendet wird, können die OLE-Strings an andere Programme übergeben werden.

pchar
Ein pointer auf einen durch #0 abgeschlossenes 8Bit character array, wird hauptsächlich in der Programmiersprache C benutzt.

pwidechar
Ein pointer auf einen durch #0 abgeschlossenes 16Bit character array, wird hauptsächlich in der Programmiersprache C benutzt.

Zeichencodierung:
In der Komputerei gibt es verschiedene Vereinbarungen, wie die einzelnen Schriftzeichen in Komputerprogrammen dargestellt werden. Beispiele:

ASCII
http://en.wikipedia.org/wiki/ASCII
Benützt einzelne 7Bit Speichereinheiten (#0..#127), kann Steuerzeichen (cariage return, linefeed, form feed...) grosse und kleine lateinische Buchstaben, Ziffern und einige Satz- und Sonderzeichen darstellen, aber keine Umlaute. Zur Speicherung eines ASCII-Zeichens wird in der Regel ein Byte verwendet, das höchstwertige Bit ist dabei immer Null.

Weitere 1 Byte Codierungen verwenden die von ASCII nicht benutzten Werte #128..#255 zur Darstellung regionenspezifischer Zeichen, Beispiele:
ISO 8859-1 (Latin 1)
http://en.wikipedia.org/wiki/ISO-8859-1##ISO-8859-1
koi18-r1
http://en.wikipedia.org/wiki/KOI8-R
ANSI wird öfters als Synonym für die aktuelle Codierung unter Windows oder für Windows-1252 verwendet.
http://en.wikipedia.org/wiki/Windows-1252
Alle diese Codierungen benötigen pro Zeichen ein Byte, durch die Begrenzung auf 256 unterscheidbare Zeichen können in einem String Sonderzeichen verschiedener Regionen nicht gemischt werden.

Unicode ist ein international genormtes Bezeichnungssystem, welches für alle existierenden Schriftzeichen einen "Codepoint" bereitstellt.
http://en.wikipedia.org/wiki/Unicode
http://unicode.org/
Ein Codepoint kann Werte zwischen $00000000 und $0010FFFF besitzen. Zur Darstellung im Komputerspeicher werden verschiedene Formate verwendet:
utf-32, ein Codepoint wird in einen 32bit Wert abgebildet, benötigt 4 Bytes pro Zeichen.
utf-16, ein Codepoint wird in einen oder zwei 16Bit Werte abgebildet, benötigt 2 oder 4 Bytes pro Zeichen.
utf-8, ein Codepoint wird in ein bis vier 8Bit Werte abgebildet, benötigt 1 bis 4 Bytes pro Zeichen.
UCS-2 ist eine Untermenge von utf-16 die einige tote Sprachen und bestimmte Zeichen des traditionellen Chinesisch und weitere selten gebrauchte Zeichen nicht enthält, benötigt 2 Bytes pro Zeichen.

FPC stellt zur Laufzeit verschiedene Automatische Umwandlungen zwischen den verschiedenen Stringtypen bereit.
shortstring ansistring, die Zeichen werden unverändert übernommen.
ansistring -> pchar,
widestring -> pwidechar, falls ansi/widestring = '' (pointer ist NIL) ist, wird ein Pointer auf #0 geliefert, andernfalls der normale Pointer auf First. Dies funktioniert, da ein ansi- oder widestring immer mit einem nachfolgenden #0 abgeschlossen ist.
ansistring -> widestring, der ansistring wird vom widestringmanager unter Verwendung der aktuellen Systemcodierung in utf-16 gewandelt, unter Linux muss dafür die unit cwstring unter uses aufgeführt werden.
widestring -> ansistring, der utf-16 codierte widestring wird vom widestringmanager in die aktuelle Systemcodierung gewandelt, unter Linux muss dafür die unit cwstring unter uses aufgeführt werden. Möglicherweise können nicht alle Zeichen des widestring in der Systemcodierung dargestellt werden.

Lazarus verwendet für Texte utf-8 codierte ansistrings auf allen Systemen, die automatische Wandlung Lazarus ansistring widestring versagt daher dort, wo nicht utf-8 verwendet wird, namentlich unter Windows. Zudem ist zu beachten, dass die Einzelzeichen eines Lazarus ansistring nicht durch Index angesprochen werden können (char1:= ansistring1[1];) da utf-8 Zeichen eine variable Länge von 1 bis 4 Bytes besitzen.

Im Gegensatz dazu verwendet MSEide+MSEgui durchgehend widestrings, automatische Konvertierung ansistring widestring funktioniert und Einzelzeichen können durch Index angesprochen werden, sofern die Codepoints im UCS2 Bereich liegen.

http://sourceforge.net/projects/mseide-msegui

Martin
Zuletzt geändert von mse am So 19. Okt 2008, 13:39, insgesamt 1-mal geändert.

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: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von mschnell »

theo hat geschrieben:Ein WideString-Element (WideChar) kann von natur aus fast alle nötigen Zeichen "adressieren" (UCS-2) obwohl mit "surrogate pair handling" auch Zeichen über 65k dargestellt werden können (UTF 16).
Nö, das glaube ich nicht. Wenn das so wäre, müsste die RTL, um ein bestimmtes Zeichen zu adressieren (x[1000]), alle vorherigen durchscannen, weil jedes Zeichen ja auch mehr als ein doppel-Byte umfassen kann. Dann hätte man auch gleich beim meist kompakteren uft8 bleiben können. Auch ist ein WideChar eine 16 Bit große Variable und darin könnten solche surrogate pairs nicht gespeichert werden.

-Michael

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: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von mse »

mschnell hat geschrieben: Dann hätte man auch gleich beim meist kompakteren uft8 bleiben können. Auch ist ein WideChar eine 16 Bit große Variable und darin könnten solche surrogate pairs nicht gespeichert werden.
Der Unterschied ist halt, dass bei utf-8 durch die Begrenzung auf ASCII lediglich Amerikaner die effiziente Adressierung mittels Index benutzen können, bei utf-16 durch UCS2 praktisch alle Erdenbürger, die Europäer auf jeden Fall. ;-)
Ebenfalls zu bedenken ist, dass Surrogate*pair* handling wesentlich einfacher und effizienter zu implementieren ist als die Behandlung der 1 bis 4 Bytes von utf-8.

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von RSE »

Sehr schön! Sehr hilfreich! Sehr übersichtlich!

Nach den Ausführungen ist ein WideString aus WideChars aufgebaut, die 16 Bit pro Zeichen benötigen. Da mir unklar war, warum man WideString benötigt, um UTF-8 zu speichern (AString := 'irgendwas';), habe ich folgenden Code ausprobiert:

Code: Alles auswählen

var
  s: String;
  w: ^longword;
  b: ^byte;
  a: array[0..19] of byte;
  i: integer;
...
  s := '1234567890';
  w := @s;  // Adresse des Startzeigers vom String in w speichern
  w := pointer(w^);  // den Startzeiger vom String in w speichern
  b := pointer(w);  // b zeigt jetzt auf das erste Zeichen im String
  for i := 0 to 9 do begin  // die ersten 10 Byte des Strings in array a speichern
    a[i] := b^;
    inc(b);
  end;
  showmessage(chr(a[0])+chr(a[1])+chr(a[2])+chr(a[3])+'#'+inttostr(SizeOf('1234567890')));
Ich hatte nun erwartet, dass nur in jedem zweiten Zeichen von a etwas sinnvolles drinsteht. Stattdessen erfolgt die Ausgabe "1234#10". Die 10 hatte ich erwartet, die 1234 nicht. Wie lässt sich das erklären? Ist String nun ein Datentyp mit 1-Byte-Zeichen oder ein WideString mit 2-Byte-Zeichen?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

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: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von mse »

RSE hat geschrieben: Ich hatte nun erwartet, dass nur in jedem zweiten Zeichen von a etwas sinnvolles drinsteht. Stattdessen erfolgt die Ausgabe "1234#10". Die 10 hatte ich erwartet, die 1234 nicht. Wie lässt sich das erklären? Ist String nun ein Datentyp mit 1-Byte-Zeichen oder ein WideString mit 2-Byte-Zeichen?
Wenn mit {$mode delphi} oder {$mode objpas}{$h+} compiliert, ist string = ansistring, im Turbo Pascal Modus ein shortstring, in beiden Fällen ein 8Bit string. Delphi 2009 verwendet für string einen Referenz gezählten 16Bit string AFAIK.

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von RSE »

Oh, du hast Recht, alle meine Units sind mit {$mode objpas}{$h+} gemarked ;-) alles klar!
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von Euklid »

Danke an alle Beteiligten(v.a. mse, theo, mschell) für die ausführlichen und nachvollziehbaren Erklärungen! :)

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

Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung

Beitrag von theo »

mschnell hat geschrieben: Nö, das glaube ich nicht. Wenn das so wäre, müsste die RTL, um ein bestimmtes Zeichen zu adressieren (x[1000]), alle vorherigen durchscannen, weil jedes Zeichen ja auch mehr als ein doppel-Byte umfassen kann.
Es kommt halt auf die RTL-Funtion an. Sowas wie WideUpperCase wird in diesem Bereich sowieso keine Rolle mehr spielen (Oder gibt es Byzantinische Musiksymbole in UpperCase ? :-)
Die Adressierung z.B. WideString[n] liefert wie immer einfach das Word bzw. den WideChar der da steht zurück. (muss nat. nicht dem visuellen n-ten entsprechen)
Du kannst dich einfach auf den Standpunkt stellen, dass bei dir keine Zeichen über $FFFF vorkommen, dann hast du damit auch nix zu tun und kannst deine WideString als UCS-2 betrachten.

Antworten