String-Typen

Aus RAD Studio (Deutsch)
Wechseln zu: Navigation, Suche

Nach oben zu Datentypen, Variablen und Konstanten - Index

Dieses Thema enthält eine Beschreibung der String-Datentypen, die in der Sprache Delphi zur Verfügung stehen. Folgende Typen werden beschrieben:

  • Kurze String-Typen (ShortString)
  • ANSI-String-Typen (AnsiString)
  • Unicode-String-Typen (UnicodeString und WideString)

Inhaltsverzeichnis

Allgemeines zu String-Typen

Ein String repräsentiert eine Zeichenfolge. Delphi unterstützt die folgenden vordefinierten String-Typen:

String-Typen :



Typ Maximale Länge Erforderlicher Speicherplatz Verwendungszweck

ShortString

255 Zeichen

2 bis 256 Byte

Abwärtskompatibilität

AnsiString

~2^31 Zeichen

4 Byte bis 2 GB

8-Bit-Zeichen (ANSI), DBCS ANSI, MBCS ANSI, Unicode-Zeichen usw.

UnicodeString

~2^30 Zeichen

4 Byte bis 2 GB

Unicode-Zeichen, 8-Bit-Zeichen (ANSI), Mehrbenutzer-Server und mehrsprachige Anwendungen

WideString

~2^30 Zeichen

4 Byte bis 2 GB

Unicode-Zeichen, Mehrbenutzer-Server und mehrsprachige Anwendungen. UnicodeString wird im Allgemeinen bevorzugt.



Anmerkung:  WideString wird aus Kompatibilitätsgründen mit dem COM-Typ BSTR bereitgestellt. Für Nicht-COM-Anwendungen sollten Sie stets UnicodeString verwenden.

Für die meisten Zwecke ist der Typ UnicodeString am besten geeignet. Der Typ string ist ein Alias für UnicodeString, nicht für AnsiString.

String-Typen können in Zuweisungen und Ausdrücken miteinander kombiniert werden. Der Compiler führt die erforderlichen Umwandlungen automatisch durch. Strings, die als Referenz an eine Funktion oder Prozedur übergeben werden (z. B. als var- und out-Parameter), müssen jedoch den korrekten Typ aufweisen. Strings können explizit in einen anderen String-Typ umgewandelt werden. Die Umwandlung eines Multibyte-Strings in einen Einzelbyte-String kann jedoch zu Datenverlust führen.

Im Folgenden werden einige spezielle String-Typen erläutert:

  • Codeseiten-abhängige AnsiStrings werden folgendermaßen definiert:Type mystring = AnsiString(CODEPAGE)Hierbei handelt es sich um einen AnsiString, der seine internen Daten in einer bestimmen Codeseite beibehält.
  • Der Typ RawByteString ist type AnsiString($FFFF). RawByteString ermöglicht die Übergabe von String-Daten jeder beliebigen Codeseite, ohne dass Codeseitenkonvertierungen vorgenommen werden müssen. RawByteString sollte nur als const- oder Wertetypparameter oder als Rückgabetyp einer Funktion verwendet werden. Er sollte nie als Referenz (mit var) übergeben und nie als Variable instantiiert werden.
  • UTF8String repräsentiert einen String, der in UTF-8 (variable Anzahl von Bytes, Unicode) codiert ist. Er ist ein codeseiten-abhängiger AnsiString-Typ mit einer UTF-8-Codeseite.

Das reservierte Wort string funktioniert wie ein allgemeiner String-Typbezeichner. Zum Beispiel:

var S: string;

Hier wird die Variable S für einen String erstellt. In Win32 interpretiert der Compiler string als UnicodeString (wenn auf das reservierte Wort keine Zahl in eckigen Klammern folgt).

In Win32 können Sie die Direktive {$H-} verwenden, wenn string als ShortString interpretiert werden soll. Dieses Vorgehen ist möglicherweise bei der Verwendung von älterem 16 Bit Delphi-Code oder Turbo Pascal-Code mit aktuellen Programmen hilfreich.

Bitte beachten Sie, dass das Schlüsselwort string auch für die Deklaration von ShortString-Typen mit einer bestimmten Länge verwendet wird (siehe Kurze String-Typen weiter unten).

Der Vergleich von Strings wird durch die Wertigkeit der Elemente an den entsprechenden Positionen definiert. Bei Vergleichen zwischen Strings von unterschiedlicher Länge wird jedes Zeichen im längeren String, dem kein Zeichen im kürzeren String entspricht, als "größer" angesehen. So ist beispielsweise "AB" größer als "A". Dies bedeutet, dass "AB" > "A" den Wert True hat. Strings mit der Länge Null repräsentieren die niedrigsten Werte.

Sie können eine String-Variable wie ein Array indizieren. Wenn S eine Nicht-UnicodeString-String-Variable und i ein Integer-Ausdruck ist, repräsentiert S[i] das i-te Byte in S, das nicht das i-te Zeichen oder überhaupt ein vollständiges Zeichen für einen Multibyte-String (MBCS) sein muss. Genauso kann das Indizieren einer UnicodeString-Variable ein Element ergeben, dass kein vollständiges Zeichen sein kann. Wenn der String Zeichen aus dem Basic Multilingual Plane (BMP) enthält, sind alle Zeichen 2 Byte groß, daher erhalten Sie bei der Indizierung des Strings Zeichen. Wenn aber einige Zeichen nicht im BMP enthalten sind, kann ein indiziertes Element ein Surrogatpaar sein - kein vollständiges Zeichen.

Die Standardfunktion Length gibt die Anzahl der Elemente in einem String zurück. Wie oben bereits erwähnt, muss die Anzahl der Elemente nicht notwendigerweise die Anzahl der Zeichen sein. Mit der Prozedur SetLength wird die Länge eines Strings festgelegt. Beachten Sie bitte, dass die Funktion SizeOf die Anzahl der Bytes zurückgibt, die zur Darstellung einer Variable oder eines Typs verwendet wird. SizeOf gibt die Anzahl der Zeichen in einem String nur für kurze Strings zurück. SizeOf gibt für alle anderen String-Typen die Anzahl der Bytes in einem Zeiger zurück, da sie Zeiger sind.

Bei einem kurzen String oder AnsiString hat S[i] den Typ AnsiChar. Bei einem WideString hat S[i] den Typ WideChar. Für Einzelbyte-Gebietsschemas (Western) weist die Anweisung MyString[2] := 'A'; dem zweiten Zeichen von MyString den Wert A zu. Im folgenden Quelltext wird MyString mit der Standardfunktion UpCase in Großbuchstaben umgewandelt:


var I: Integer;
begin
   I := Length(MyString);
   while I > 0 do
    begin
       MyString[I] := UpCase(MyString[I]);
       I := I -1;
    end;
end;

Wenn Sie Strings auf diese Weise indizieren, müssen Sie darauf achten, dass Sie nicht über das Ende des Strings hinaus schreiben, da dies zu einer Zugriffsverletzung führen würde. Außerdem sollten Sie Indizes für Strings nicht als var-Parameter übergeben, da dies ineffizienten Code ergibt.

Sie können einer String-Variablen den Wert einer String-Konstanten oder eines anderen Ausdrucks zuweisen, der einen String zurückliefert. Die Länge des Strings ändert sich bei der Zuweisung dynamisch. Beispiele:


MyString := 'Hello world!';
MyString := 'Hello' + 'world';
MyString := MyString + '!';
MyString := ' '; { Leerzeichen }
MyString := ;  { Leer-String }

Kurze String-Typen

Ein ShortString hat eine Länge von 0 bis 255 Zeichen. Obwohl sich seine Länge dynamisch ändern kann, beträgt die statische Speicherplatzzuweisung immer 256 Bytes. Im ersten Byte wird die Länge des Strings gespeichert, die restlichen 255 Byte stehen für die Zeichen zur Verfügung. Wenn S eine ShortString-Variable ist, gibt Ord(S[0]) die Länge von S zurück (dasselbe Ergebnis erzielen Sie mit Length(S)). Durch Zuweisung eines Wertes an S[0] können Sie (wie durch einen Aufruf von SetLength) die Länge von S ändern. ShortString wird nur aus Gründen der Abwärtskompatibilität mitgeführt.

Delphi unterstützt kurze String-Typen (Untertypen von ShortString), deren maximale Länge zwischen 0 und 255 Zeichen liegen kann. Diese Typen werden mit einer Zahl in eckigen Klammern dargestellt, die auf das reservierte Wort string folgt. Zum Beispiel:

var MyString: string[100];

Hier wird die Variable MyString mit einer maximalen Länge von 100 Zeichen erstellt. Die folgenden Deklarationen sind mit der obigen Zeile identisch:


type CString = string[100];
var MyString: CString;

Bei Variablen, die auf diese Weise deklariert werden, wird dem Typ nur so viel Speicherplatz zugewiesen, wie für die angegebene Länge plus ein Byte erforderlich ist. Im obigen Beispiel belegt MyString 101 Byte. Für eine Variable des vordefinierten Typs ShortString wären dagegen 256 Byte erforderlich.

Bei einer Wertzuweisung an eine kurze String-Variable wird der String abgeschnitten, wenn die maximale Länge für den Typ überschritten wird.

Die Standardfunktionen High und Low bearbeiten Variablen und Typbezeichner für kurze Strings. High liefert die maximale Länge des kurzen String-Typs, während Low Null zurückgibt.

AnsiString

AnsiString repräsentiert einen dynamisch zugewiesenen String, dessen maximale Länge nur durch den verfügbaren Speicherplatz begrenzt wird.

Eine AnsiString-Variable ist eine Struktur, die String-Informationen enthält. Wenn die Variable leer ist (also einen String der Länge Null enthält), hat der Zeiger den Wert nil, und der String belegt keinen zusätzlichen Speicherplatz. Ist die Variable nicht leer, zeigt sie auf einen dynamisch zugewiesenen Speicherblock, der einen String-Wert enthält. Da dieser Speicherplatz auf dem Heap reserviert und vollkommen automatisch verwaltet wird, erfordert er keinerlei Benutzercode. Die Struktur AnsiString enthält eine 32-Bit Längenangabe, einen 32-Bit Referenzzähler, eine 16-Bit Datenlänge, die die Anzahl der Bytes pro Zeichen angibt, und eine 16-Bit Codeseite.

Ein AnsiString repräsentiert ein Einzelbyte-String. Bei einem Einzelbyte-Zeichensatz (SBCS = Single-Byte Character Set) repräsentiert jedes Byte eines Strings ein Zeichen. In einem Multibyte-Zeichensatz (MBCS = Multi-Byte Character Set) sind die Elemente weiterhin Einzelbytes, aber einige Zeichen werden mit einem einzelnen Byte und andere mit mehreren Bytes dargestellt. Multibyte-Zeichensätze, insbesondere Doppelbyte-Zeichensätze (DBCS = Double-Byte Character Set), werden in erster Linie für asiatische Sprachen verwendet. Ein AnsiString kann MBCS-Zeichen enthalten.

Die Indizierung von AnsiString beginnt bei 1. Eine zuverlässige Indizierung von Multibyte-Strings ist nicht möglich, da S[i] das i-te Byte (und nicht notwendigerweise das i-te Zeichen) in S darstellt. Das i-te Byte kann ein einzelnes Zeichen oder Teil eines Zeichens sein. Jedoch gibt es für alle Standardfunktionen zur AnsiString-Verarbeitung multibytefähige Entsprechungen, die auch die Besonderheiten länderspezifischer Zeichensätze berücksichtigen. Die Namen von Multibyte-Funktionen beginnen normalerweise mit dem Wort Ansi. Beispielsweise trägt die Multibyte-Version von StrPos den Namen AnsiStrPos. Die Unterstützung von Multibyte-Zeichen ist betriebssystemabhängig und basiert auf dem verwendeten Gebietsschema.

Da AnsiString-Variablen Zeiger haben, können zwei oder mehrere dieser Variablen auf denselben Wert zeigen, ohne zusätzlichen Speicherplatz zu belegen. Der Compiler nützt dies zur Einsparung von Ressourcen. Auch Zuweisungen werden schneller ausgeführt. Sobald eine AnsiString-Variable freigegeben oder mit einem neuen Wert belegt wird, wird der Referenzzähler des alten AnsiString (d.h. des vorhergehenden Wertes der Variablen) verringert und der Referenzzähler des neuen Wertes (falls ein solcher zugewiesen wurde) erhöht. Erreicht der Referenzzähler eines Strings den Wert Null, wird der belegte Speicherplatz freigegeben. Dieser Vorgang wird als Referenzzählung bezeichnet. Wenn der Wert eines einzelnen Zeichens im String über einen Index geändert werden soll, wird eine Kopie des Strings angelegt. Dies ist aber nur möglich, wenn der betreffende Referenzzähler größer als 1 ist. Diesen Vorgang nennt man Copy-on-Write-Semantik.

UnicodeString

Der Typ UnicodeString repräsentiert einen dynamisch zugewiesenen Unicode-String, dessen maximale Länge nur durch den verfügbaren Speicherplatz begrenzt wird.

In einem Unicode-Zeichensatz wird jedes Zeichen durch ein oder zwei Byte repräsentiert. Unicode verfügt über mehrere Formate zur Unicode-Umwandlung, die verschiedene aber äquivalente Zeichencodierungen verwenden, die schnell ineinander umgewandelt werden können.

In UTF-8. können Zeichen beispielsweise von 1 bis 4 Byte groß sein. In UTF-8 entsprechen die ersten 128 Unicode-Zeichen den US-ASCII-Zeichen.

UTF-16 ist eine weitere häufig verwendete Unicode-Codierung, in der Zeichen entweder 2 oder 4 Byte groß sind. Die Mehrzahl der weltweit verwendeten Schriftzeichen befindet sich im Basic Multilingual Plane und kann mit 2 Byte repräsentiert werden. Die übrigen Zeichen benötigen zwei 2-Byte-Zeichen, die Surrogatpaare genannt werden.

UTF-32 repräsentiert jedes Zeichen mit 4 Byte.

Win32 unterstützt Einzelbyte- und Multibyte-Zeichensätze sowie den Unicode-Zeichensatz. Windows unterstützt UTF-16.

Weitere Informationen finden Sie unter Unicode Standard.

Der Typ UnicodeString hat genau dieselbe Struktur wie der Typ AnsiString. UnicodeString-Daten werden in UTF-16 codiert.

Da UnicodeString und AnsiString die gleiche Struktur haben, arbeiten sie auch sehr ähnlich. Wenn eine UnicodeString-Variable leer ist, benötigt sie keinen zusätzlichen Speicherplatz. Wenn sie nicht leer ist, zeigt sie auf einen dynamisch zugewiesenen Speicherblock, der den String-Wert enthält, Die Speicherbehandlung dafür ist für den Benutzer ersichtlich. UnicodeString-Variablen verfügen über Referenzzähler, und zwei oder mehrere dieser Variablen können denselben Wert referenzieren, ohne zusätzlichen Speicherplatz zu belegen.

Instanzen von UnicodeString können Zeichen indizieren. Die Indizierung ist 1-basiert, genau wie bei AnsiString.

UnicodeString ist zu allen anderen String-Typen zuweisungskompatibel. Zuweisungen zwischen AnsiString und UnicodeString führen aber die entsprechenden Auf- oder Abkonvertierungen durch. Bitte beachten Sie, dass eine Zuweisung eines UnicodeString-Typs zu einem AnsiString-Typ nicht empfohlen wird und zu Datenverlusten führen kann.

Delphi kann Unicode-Zeichen und -Strings auch über die Typen WideChar, PWideChar und WideString unterstützen.

Weitere Informationen zur Verwendung von Unicode finden Sie unter Unicode in der IDE und Anwendungen für Unicode anpassen.

WideString

Der Typ WideString repräsentiert einen dynamisch zugewiesenen String mit 16-Bit-Unicode-Zeichen. Er ähnelt in vielerlei Hinsicht dem Typ AnsiString. In Win32 ist der Typ WideString kompatibel mit dem COM-Typ BSTR.

WideString ist für COM-Anwendungen geeignet. WideString verfügt aber über keinen Referenzzähler, deshalb ist UnicodeString für andere Anwendungstypen flexibler und effizienter.

Eine zuverlässige Indizierung von WideString-Multibyte-Strings ist nicht möglich, da S[i] das i-te Element (und nicht notwendigerweise das i-te Zeichen) in S repräsentiert.

In Delphi sind Char- und PChar-Typen WideChar- bzw. PWideChar-Typen.

Nullterminierte Strings

In vielen Programmiersprachen, z. B. in C und C++, fehlt ein spezieller String-Datentyp. Diese Sprachen und die mit ihnen programmierten Umgebungen verwenden so genannte nullterminierte Strings. Ein nullterminierter String ist ein Zeichen-Array, dessen Index bei 0 beginnt und das mit einer NULL (#0) endet. Da das Array keine Längenangabe hat, wird das Ende des Strings durch das erste NULL-Zeichen markiert. Die Verarbeitung nullterminierter Strings erfolgt in Delphi mithilfe von Routinen, die sich in der Unit SysUtils befinden (siehe Standardroutinen und E/A). Dies ist beispielsweise erforderlich, wenn Sie Daten gemeinsam mit Systemen benutzen, die nullterminierte Strings verwenden.

Hier einige Beispiele für die Deklaration von Typen, die nullterminierte Strings speichern können:


type
  TIdentifier = array[0..15] of Char;
  TFileName = array[0..259] of Char;
  TMemoText = array[0..1023] of WideChar;

Wenn die erweiterte Syntax aktiviert ist ({$X+}), können Sie einem statisch zugewiesenen Zeichen-Array, dessen Index bei 0 beginnt, eine String-Konstante zuweisen. Mit einem dynamischen Array ist dies nicht möglich. Wenn Sie eine Array-Konstante mit einem String initialisieren, der kürzer als die deklarierte Länge des Arrays ist, werden die verbleibenden Zeichen auf #0 gesetzt.

Zeiger, Arrays und String-Konstanten

Bei der Bearbeitung von nullterminierten Strings werden oft Zeiger benötigt. (Siehe Zeiger und Zeigertypen.) String-Konstanten sind zuweisungskompatibel zu den Typen PChar und PWideChar, die Zeiger auf nullterminierte Arrays mit Char- und WideChar-Werten darstellen. Zum Beispiel:


var P: PChar;
  ...
P := 'Hello world!'

P zeigt auf einen Speicherbereich, der eine nullterminierte Kopie von "Hello world!" enthält. Dieses Verfahren ist zum Folgenden äquivalent:


const TempString: array[0..12] of Char = 'Hello world!';
var P: PChar;
   ...
P := @TempString[0];

Sie können String-Konstanten auch an Funktionen übergeben, die Wert- oder const-Parameter des Typs PChar oder PWideChar akzeptieren, z. B. StrUpper('Hello world!'). Der Compiler erzeugt (wie bei Zuweisungen an PChar) eine nullterminierte Kopie des Strings und übergibt der Funktion einen Zeiger auf diese Kopie. Außerdem können Sie PChar- und PWideChar-Konstanten einzeln oder in strukturierten Typen mit String-Literalen initialisieren. Beispiele:


const
  Message: PChar = 'Programm beendet';
  Prompt: PChar = 'Werte eingeben: ';
  Digits: array[0..9] of PChar = ('Null', 'Eins', 'Zwei', 'Drei', 'Vier', 'Fünf', 'Sechs', 'Sieben', 'Acht', 'Neun');

Zeichen-Arrays, deren Index bei 0 beginnt, sind mit PChar und PWideChar kompatibel. Wenn Sie anstelle eines Zeigerwertes ein Zeichen-Array verwenden, wandelt der Compiler das Array in eine Zeiger-Konstante um, deren Wert der Adresse des ersten Elements im Array entspricht. Zum Beispiel:


var
  MyArray: array[0..32] of Char;
  MyPointer: PChar;
begin
  MyArray := 'Hello';
  MyPointer := MyArray;
  SomeProcedure(MyArray);
  SomeProcedure(MyPointer);
end;

Dieser Programmcode ruft SomeProcedure zweimal mit demselben Wert auf.

Ein Zeichenzeiger kann wie ein Array indiziert werden. Im obigen Beispiel gibt MyPointer[0] den Wert H zurück. Der Index legt einen Offset fest, der zu dem Zeiger vor der Dereferenzierung addiert wird. Bei PWideChar-Variablen wird der Index automatisch mit zwei multipliziert. Wenn es sich bei P um einen Zeichenzeiger handelt, ist P[0] identisch mit P^ und bezeichnet das erste Zeichen im Array, P[1] das zweite Zeichen usw. P[-1] bezeichnet das "Zeichen", das unmittelbar links neben P[0] steht. Der Compiler führt für diese Indizes aber keine Bereichsprüfung durch.

Das folgende Beispiel zeigt anhand der Funktion StrUpper, wie unter Verwendung der Zeigerindizierung ein nullterminierter String durchlaufen wird:


function StrUpper(Dest, Source: PChar; MaxLen: Integer): PChar;
var
  I: Integer;
begin
  I := 0;
  while (I < MaxLen) and (Source[I] <> #0) do
  begin
    Dest[I] := UpCase(Source[I]);
    Inc(I);
  end;
  Dest[I] := #0;
  Result := Dest;
end;

Kombinieren von Delphi-Strings und nullterminierten Strings

Strings (AnsiString- und UnicodeString-Werte) und nullterminierte Strings (PChar-Werte) lassen sich in Ausdrücken und Zuweisungen kombinieren. Außerdem können PChar-Werte an Funktionen und Prozeduren übergeben werden, die String-Parameter akzeptieren. Die Zuweisung S := P, in der S eine String-Variable und P ein PChar-Ausdruck ist, kopiert einen nullterminierten String in einen String.

Wenn in einer binären Operation der eine Operand ein String und der andere ein PChar-Ausdruck ist, wird der PChar-Operand in einen UnicodeString umgewandelt.

Sie können einen PChar-Wert als UnicodeString verwenden. Dies ist hilfreich, wenn eine String-Operation für zwei PChar-Werte durchgeführt werden soll. Zum Beispiel:

S := string(P1) + string(P2);

Sie können einen UnicodeString- oder AnsiString-String auch in einen nullterminierten String umwandeln. Für Zeiger-Operatoren gelten die folgenden Regeln:

  • Wenn S ein UnicodeString-String ist, wird S mit PChar(S) in einen nullterminierten String umgewandelt. Das Ergebnis ist ein Zeiger auf das erste Zeichen in S. Solche Typumwandlungen werden für die Windows-API verwendet. Wenn es sich beispielsweise bei Str1 und Str2 um UnicodeString-Strings handelt, können Sie die Win32 API-Funktion MessageBox folgendermaßen aufrufen: MessageBox(0, PChar(Str1), PChar(Str2), MB_OK);. Verwenden Sie PAnsiChar(S), wenn S ein AnsiString ist.
  • Außerdem haben Sie die Möglichkeit, mit Pointer(S) einen String in einen untypisierten Zeiger umzuwandeln. Wenn S aber leer ist, ergibt die Umwandlung nil.
  • PChar(S) gibt stets einen Zeiger auf einen Speicherblock zurück. Wenn S leer ist, wird ein Zeiger auf #0 zurückgegeben.
  • Wenn Sie eine UnicodeString- oder AnsiString-Variable in einen Zeiger konvertieren, bleibt dieser gültig, bis die Variable den Gültigkeitsbereich verlässt oder ihr ein neuer Wert zugewiesen wird. Wenn Sie einen beliebigen anderen String-Ausdruck in einen Zeiger umwandeln, ist der Zeiger nur innerhalb der Anweisung gültig, in der die Typumwandlung durchgeführt wird.
  • Nach der Konvertierung eines UnicodeString- oder AnsiString-Ausdrucks in einen Zeiger sollten Sie den Zeiger als schreibgeschützt ansehen. Der String kann über den Zeiger nur dann gefahrlos geändert werden, wenn folgende Bedingungen erfüllt sind:

Diese Regeln gelten auch, wenn Sie WideString-Werte mit PWideChar-Werten kombinieren.

Siehe auch

In anderen Sprachen