Embarcadero Delphi
Cordes
Recherche…
Types de chaînes
Delphi a les types de chaînes suivants (par ordre de popularité):
Type | Longueur maximale | Taille minimum | La description |
---|---|---|---|
string | 2 Go | 16 octets | Une chaîne gérée. Un alias pour AnsiString via Delphi 2007 et un alias pour UnicodeString partir de Delphi 2009. |
UnicodeString | 2 Go | 16 octets | Une chaîne gérée au format UTF-16. |
AnsiString | 2 Go | 16 octets | Une chaîne gérée au format ANSI pré-Unicode. À partir de Delphi 2009, il comporte un indicateur de page de code explicite. |
UTF8String | 2 Go | 16 octets | Une chaîne gérée au format UTF-8, implémentée en tant que AnsiString avec une page de codes UTF-8. |
ShortString | 255 caractères | 2 octets | Une chaîne héritée, de longueur fixe, non gérée avec très peu de charge |
WideString | 2 Go | 4 octets | Destiné à l'interopérabilité COM, une chaîne gérée au format UTF-16. Equivalent au type Windows BSTR . |
UnicodeString
et AnsiString
sont des références comptées et des copies sur écriture (COW).
ShortString
et WideString
ne sont pas comptés par référence et n'ont pas de sémantique COW.
Cordes
uses
System.Character;
var
S1, S2: string;
begin
S1 := 'Foo';
S2 := ToLower(S1); // Convert the string to lower-case
S1 := ToUpper(S2); // Convert the string to upper-case
Chars
uses
Character;
var
C1, C2: Char;
begin
C1 := 'F';
C2 := ToLower(C1); // Convert the char to lower-case
C1 := ToUpper(C2); // Convert the char to upper-case
La clause uses
doit être System.Character
si la version est XE2 ou supérieure.
Majuscule et minuscule
uses
SysUtils;
var
S1, S2: string;
begin
S1 := 'Foo';
S2 := LowerCase(S1); // S2 := 'foo';
S1 := UpperCase(S2); // S1 := 'FOO';
Affectation
Assigner une chaîne à différents types de chaînes et comment l'environnement d'exécution se comporte à leur égard. Allocation de mémoire, comptage de références, accès indexé aux caractères et erreurs de compilation décrites brièvement, le cas échéant.
var
SS5: string[5]; {a shortstring of 5 chars + 1 length byte, no trailing `0`}
WS: Widestring; {managed pointer, with a bit of compiler support}
AS: ansistring; {ansistring with the default codepage of the system}
US: unicodestring; {default string type}
U8: UTF8string;//same as AnsiString(65001)
A1251: ansistring(1251); {ansistring with codepage 1251: Cryllic set}
RB: RawbyteString; {ansistring with codepage 0: no conversion set}
begin
SS5:= 'test'; {S[0] = Length(SS254) = 4, S[1] = 't'...S[5] = undefined}
SS5:= 'test1'; {S[0] = 5, S[5] = '1', S[6] is out of bounds}
SS5:= 'test12'; {compile time error}
WS:= 'test'; {WS now points to a constant unicodestring hard compiled into the data segment}
US:= 'test'+IntToStr(1); {New unicode string is created with reference count = 1}
WS:= US; {SysAllocateStr with datacopied to dest, US refcount = 1 !}
AS:= US; {the UTF16 in US is converted to "extended" ascii taking into account the codepage in AS possibly losing data in the process}
U8:= US; {safe copy of US to U8, all data is converted from UTF16 into UTF8}
RB:= US; {RB = 'test1'#0 i.e. conversion into RawByteString uses system default codepage}
A1251:= RB; {no conversion takes place, only reference copied. Ref count incremented }
Comptage de référence
Le comptage des références sur les chaînes est sécurisé pour les threads. Les verrous et les gestionnaires d'exceptions sont utilisés pour protéger le processus. Considérez le code suivant, avec des commentaires indiquant où le compilateur insère du code au moment de la compilation pour gérer les comptes de référence:
procedure PassWithNoModifier(S: string);
// prologue: Increase reference count of S (if non-negative),
// and enter a try-finally block
begin
// Create a new string to hold the contents of S and 'X'. Assign the new string to S,
// thereby reducing the reference count of the string S originally pointed to and
// brining the reference count of the new string to 1.
// The string that S originally referred to is not modified.
S := S + 'X';
end;
// epilogue: Enter the `finally` section and decrease the reference count of S, which is
// now the new string. That count will be zero, so the new string will be freed.
procedure PassWithConst(const S: string);
var
TempStr: string;
// prologue: Clear TempStr and enter a try-finally block. No modification of the reference
// count of string referred to by S.
begin
// Compile-time error: S is const.
S := S + 'X';
// Create a new string to hold the contents of S and 'X'. TempStr gets a reference count
// of 1, and reference count of S remains unchanged.
TempStr := S + 'X';
end;
// epilogue: Enter the `finally` section and decrease the reference count of TempStr,
// freeing TempStr because its reference count will be zero.
Comme indiqué ci-dessus, l'introduction d'une chaîne locale temporaire pour contenir les modifications apportées à un paramètre implique la même surcharge que pour apporter des modifications directement à ce paramètre. Déclarer une chaîne const
n'évite que le comptage de références lorsque le paramètre de chaîne est réellement en lecture seule. Cependant, pour éviter toute fuite de détails d'implémentation en dehors d'une fonction, il est conseillé de toujours utiliser l'un des paramètres const
, var
ou out
on string.
Encodages
Les types de chaînes comme UnicodeString, AnsiString, WideString et UTF8String sont stockés dans une mémoire à l'aide de leur codage respectif (voir Types de chaînes pour plus de détails). L'affectation d'un type de chaîne à une autre peut entraîner une conversion. Type string est conçu pour encoder indépendamment - vous ne devriez jamais utiliser sa représentation interne.
La classe Sysutils.TEncoding
fournit la méthode GetBytes
pour convertir la string
en TBytes
(tableau d'octets) et GetString
pour convertir TBytes
en string
. La classe Sysutils.TEncoding
fournit également de nombreux encodages prédéfinis en tant que propriétés de classe.
Une façon de traiter les encodages consiste à utiliser uniquement string
type de string
dans votre application et à utiliser TEncoding
chaque fois que vous devez utiliser un codage spécifique - généralement dans les opérations d'E / S, les appels DLL, etc.
procedure EncodingExample;
var hello,response:string;
dataout,datain:TBytes;
expectedLength:integer;
stringStream:TStringStream;
stringList:TStringList;
begin
hello := 'Hello World!Привет мир!';
dataout := SysUtils.TEncoding.UTF8.GetBytes(hello); //Conversion to UTF8
datain := SomeIOFunction(dataout); //This function expects input as TBytes in UTF8 and returns output as UTF8 encoded TBytes.
response := SysUtils.TEncoding.UTF8.GetString(datain); //Convertsion from UTF8
//In case you need to send text via pointer and length using specific encoding (used mostly for DLL calls)
dataout := SysUtils.TEncoding.GetEncoding('ISO-8859-2').GetBytes(hello); //Conversion to ISO 8859-2
DLLCall(addr(dataout[0]),length(dataout));
//The same is for cases when you get text via pointer and length
expectedLength := DLLCallToGetDataLength();
setLength(datain,expectedLength);
DLLCall(addr(datain[0]),length(datain));
response := Sysutils.TEncoding.GetEncoding(1250).getString(datain);
//TStringStream and TStringList can use encoding for I/O operations
stringList:TStringList.create;
stringList.text := hello;
stringList.saveToFile('file.txt',SysUtils.TEncoding.Unicode);
stringList.destroy;
stringStream := TStringStream(hello,SysUtils.TEncoding.Unicode);
stringStream.saveToFile('file2.txt');
stringStream.Destroy;
end;